home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / ops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-06  |  77.0 KB  |  3,272 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
  11.  *      op_change, op_yank, do_put, do_join
  12.  */
  13.  
  14. #include "vim.h"
  15.  
  16. /*
  17.  * Number of registers.
  18.  *    0 = unnamed register, for normal yanks and puts
  19.  *   1..9 = number registers, for deletes
  20.  * 10..35 = named registers
  21.  *     36 = delete register (-)
  22.  *     37 = Clipboard register (*). Only if USE_CLIPBOARD defined
  23.  */
  24. #ifdef USE_CLIPBOARD
  25. # define NUM_REGISTERS        38
  26. #else
  27. # define NUM_REGISTERS        37
  28. #endif
  29.  
  30. /*
  31.  * Symbolic names for some registers.
  32.  */
  33. #define DELETION_REGISTER    36
  34. #ifdef USE_CLIPBOARD
  35. # define CLIPBOARD_REGISTER    37
  36. #endif
  37.  
  38. /*
  39.  * Each yank register is an array of pointers to lines.
  40.  */
  41. static struct yankreg
  42. {
  43.     char_u    **y_array;    /* pointer to array of line pointers */
  44.     linenr_t    y_size;        /* number of lines in y_array */
  45.     char_u    y_type;        /* MLINE, MCHAR or MBLOCK */
  46. } y_regs[NUM_REGISTERS];
  47.  
  48. static struct yankreg    *y_current;        /* ptr to current yankreg */
  49. static int        y_append;        /* TRUE when appending */
  50. static struct yankreg    *y_previous = NULL; /* ptr to last written yankreg */
  51.  
  52. /*
  53.  * structure used by block_prep, op_delete and op_yank for blockwise operators
  54.  */
  55. struct block_def
  56. {
  57.     int        startspaces;
  58.     int        endspaces;
  59.     int        textlen;
  60.     char_u    *textstart;
  61.     colnr_t    textcol;
  62. };
  63.  
  64. #ifdef WANT_EVAL
  65. static char_u    *get_expr_line __ARGS((void));
  66. #endif
  67. static void    get_yank_register __ARGS((int regname, int writing));
  68. static int    stuff_yank __ARGS((int, char_u *));
  69. static int    put_in_typebuf __ARGS((char_u *s, int colon));
  70. static void    stuffescaped __ARGS((char_u *arg));
  71. static int    get_spec_reg __ARGS((int regname, char_u **argp, int *allocated));
  72. static void    free_yank __ARGS((long));
  73. static void    free_yank_all __ARGS((void));
  74. static void    block_prep __ARGS((OPARG *oap, struct block_def *, linenr_t, int));
  75. #if defined(USE_CLIPBOARD) || defined(WANT_EVAL)
  76. static void    str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str, long len));
  77. #endif
  78. static int    same_leader __ARGS((int, char_u *, int, char_u *));
  79. static int    fmt_check_par __ARGS((linenr_t, int *, char_u **));
  80.  
  81. /*
  82.  * op_shift - handle a shift operation
  83.  */
  84.     void
  85. op_shift(oap, curs_top, amount)
  86.     OPARG        *oap;
  87.     int            curs_top;
  88.     int            amount;
  89. {
  90.     long        i;
  91.     int            first_char;
  92.  
  93.     if (u_save((linenr_t)(curwin->w_cursor.lnum - 1),
  94.          (linenr_t)(curwin->w_cursor.lnum + oap->line_count)) == FAIL)
  95.     return;
  96.     for (i = oap->line_count; --i >= 0; )
  97.     {
  98.     first_char = *ml_get_curline();
  99.     if (first_char == NUL)                /* empty line */
  100.         curwin->w_cursor.col = 0;
  101.     /*
  102.      * Don't move the line right if it starts with # and p_si is set.
  103.      */
  104.     else
  105. #if defined(SMARTINDENT) || defined(CINDENT)
  106.         if (first_char != '#' || (
  107. # ifdef SMARTINDENT
  108.              !curbuf->b_p_si
  109. # endif
  110. # if defined(SMARTINDENT) && defined(CINDENT)
  111.                 &&
  112. # endif
  113. # ifdef CINDENT
  114.              (!curbuf->b_p_cin || !in_cinkeys('#', ' ', TRUE))
  115. # endif
  116.                     ))
  117. #endif
  118.     {
  119.         /* if (oap->block_mode)
  120.             shift the block, not the whole line
  121.         else */
  122.         shift_line(oap->op_type == OP_LSHIFT, p_sr, amount);
  123.     }
  124.     ++curwin->w_cursor.lnum;
  125.     }
  126.  
  127.     if (curs_top)        /* put cursor on first line, for ">>" */
  128.     {
  129.     curwin->w_cursor.lnum -= oap->line_count;
  130.     beginline(BL_SOL | BL_FIX);   /* shift_line() may have set cursor.col */
  131.     }
  132.     else
  133.     --curwin->w_cursor.lnum;    /* put cursor on last line, for ":>" */
  134.     update_topline();
  135.     update_screen(NOT_VALID);
  136.  
  137.     if (oap->line_count > p_report)
  138.        smsg((char_u *)"%ld line%s %ced %d time%s", oap->line_count,
  139.           plural(oap->line_count), (oap->op_type == OP_RSHIFT) ? '>' : '<',
  140.              amount, plural((long)amount));
  141.  
  142.     /*
  143.      * Set "'[" and "']" marks.
  144.      */
  145.     curbuf->b_op_start = oap->start;
  146.     curbuf->b_op_end = oap->end;
  147. }
  148.  
  149. /*
  150.  * shift the current line one shiftwidth left (if left != 0) or right
  151.  * leaves cursor on first blank in the line
  152.  */
  153.     void
  154. shift_line(left, round, amount)
  155.     int left;
  156.     int    round;
  157.     int    amount;
  158. {
  159.     int        count;
  160.     int        i, j;
  161.     int        p_sw = (int)curbuf->b_p_sw;
  162.  
  163.     count = get_indent();        /* get current indent */
  164.  
  165.     if (round)                /* round off indent */
  166.     {
  167.     i = count / p_sw;        /* number of p_sw rounded down */
  168.     j = count % p_sw;        /* extra spaces */
  169.     if (j && left)            /* first remove extra spaces */
  170.         --amount;
  171.     if (left)
  172.     {
  173.         i -= amount;
  174.         if (i < 0)
  175.         i = 0;
  176.     }
  177.     else
  178.         i += amount;
  179.     count = i * p_sw;
  180.     }
  181.     else        /* original vi indent */
  182.     {
  183.     if (left)
  184.     {
  185.         count -= p_sw * amount;
  186.         if (count < 0)
  187.         count = 0;
  188.     }
  189.     else
  190.         count += p_sw * amount;
  191.     }
  192.     set_indent(count, TRUE);        /* set new indent */
  193. }
  194.  
  195. #if defined(LISPINDENT) || defined(CINDENT)
  196. /*
  197.  * op_reindent - handle reindenting a block of lines for C or lisp.
  198.  *
  199.  * mechanism copied from op_shift, above
  200.  */
  201.     void
  202. op_reindent(oap, how)
  203.     OPARG    *oap;
  204.     int        (*how) __ARGS((void));
  205. {
  206.     long    i;
  207.     char_u    *l;
  208.     int        count;
  209.  
  210.     if (u_save((linenr_t)(curwin->w_cursor.lnum - 1),
  211.          (linenr_t)(curwin->w_cursor.lnum + oap->line_count)) == FAIL)
  212.     return;
  213.  
  214.     for (i = oap->line_count; --i >= 0 && !got_int; )
  215.     {
  216.     /* it's a slow thing to do, so give feedback so there's no worry that
  217.      * the computer's just hung. */
  218.  
  219.     if (       (i % 50 == 0
  220.             || i == oap->line_count - 1)
  221.         && oap->line_count > p_report)
  222.         smsg((char_u *)"%ld line%s to indent... ", i, plural(i));
  223.  
  224.     /*
  225.      * Be vi-compatible: For lisp indenting the first line is not
  226.      * indented, unless there is only one line.
  227.      */
  228. #ifdef LISPINDENT
  229.     if (i != oap->line_count - 1 || oap->line_count == 1 ||
  230.                                how != get_lisp_indent)
  231. #endif
  232.     {
  233.         l = skipwhite(ml_get_curline());
  234.         if (*l == NUL)            /* empty or blank line */
  235.         count = 0;
  236.         else
  237.         count = how();            /* get the indent for this line */
  238.  
  239.         set_indent(count, TRUE);
  240.     }
  241.     ++curwin->w_cursor.lnum;
  242.     }
  243.  
  244.     /* put cursor on first non-blank of indented line */
  245.     curwin->w_cursor.lnum -= oap->line_count;
  246.     beginline(BL_SOL | BL_FIX);
  247.  
  248.     update_topline();
  249.     update_screen(NOT_VALID);
  250.  
  251.     if (oap->line_count > p_report)
  252.     {
  253.     i = oap->line_count - (i + 1);
  254.     smsg((char_u *)"%ld line%s indented ", i, plural(i));
  255.     }
  256.     /* set '[ and '] marks */
  257.     curbuf->b_op_start = oap->start;
  258.     curbuf->b_op_end = oap->end;
  259. }
  260. #endif /* defined(LISPINDENT) || defined(CINDENT) */
  261.  
  262. #ifdef WANT_EVAL
  263. /*
  264.  * Keep the last expression line here, for repeating.
  265.  */
  266. static char_u    *expr_line = NULL;
  267.  
  268. /*
  269.  * Get an expression for the "\"=expr1" or "CTRL-R =expr1"
  270.  * Returns '=' when OK, NUL otherwise.
  271.  */
  272.     int
  273. get_expr_register()
  274. {
  275.     char_u    *new_line;
  276.  
  277.     new_line = getcmdline('=', 0L, 0);
  278.     if (new_line == NULL)
  279.     return NUL;
  280.     if (*new_line == NUL)    /* use previous line */
  281.     vim_free(new_line);
  282.     else
  283.     set_expr_line(new_line);
  284.     return '=';
  285. }
  286.  
  287. /*
  288.  * Set the expression for the '=' register.
  289.  * Argument must be an allocated string.
  290.  */
  291.     void
  292. set_expr_line(new_line)
  293.     char_u    *new_line;
  294. {
  295.     vim_free(expr_line);
  296.     expr_line = new_line;
  297. }
  298.  
  299. /*
  300.  * Get the result of the '=' register expression.
  301.  * Returns a pointer to allocated memory, or NULL for failure.
  302.  */
  303.     static char_u *
  304. get_expr_line()
  305. {
  306.     if (expr_line == NULL)
  307.     return NULL;
  308.     return eval_to_string(expr_line, NULL);
  309. }
  310. #endif /* WANT_EVAL */
  311.  
  312. /*
  313.  * Check if 'regname' is a valid name of a yank register.
  314.  * Note: There is no check for 0 (default register), caller should do this
  315.  */
  316.     int
  317. valid_yank_reg(regname, writing)
  318.     int        regname;
  319.     int        writing;        /* if TRUE check for writable registers */
  320. {
  321.     if (regname > '~')
  322.     return FALSE;
  323.     if (       isalnum(regname)
  324.         || (!writing && vim_strchr((char_u *)
  325. #ifdef WANT_EVAL
  326.                     ".%#:="
  327. #else
  328.                     ".%#:"
  329. #endif
  330.                     , regname) != NULL)
  331.         || regname == '"'
  332.         || regname == '-'
  333. #ifdef USE_CLIPBOARD
  334.         || (clipboard.available && regname == '*')
  335. #endif
  336.                             )
  337.     return TRUE;
  338.     return FALSE;
  339. }
  340.  
  341. /*
  342.  * Set y_current and y_append, according to the value of "regname".
  343.  *
  344.  * If regname is 0 and writing, use register 0
  345.  * If regname is 0 and reading, use previous register
  346.  */
  347.     static void
  348. get_yank_register(regname, writing)
  349.     int        regname;
  350.     int        writing;
  351. {
  352.     int        i;
  353.  
  354.     y_append = FALSE;
  355.     if (((regname == 0 && !writing) || regname == '"') && y_previous != NULL)
  356.     {
  357.     y_current = y_previous;
  358.     return;
  359.     }
  360.     i = regname;
  361.     if (isdigit(i))
  362.     i -= '0';
  363.     else if (islower(i))
  364.     i -= 'a' - 10;
  365.     else if (isupper(i))
  366.     {
  367.     i -= 'A' - 10;
  368.     y_append = TRUE;
  369.     }
  370.     else if (regname == '-')
  371.     i = DELETION_REGISTER;
  372. #ifdef USE_CLIPBOARD
  373.     else if (clipboard.available && regname == '*')
  374.     i = CLIPBOARD_REGISTER;
  375. #endif
  376.     else        /* not 0-9, a-z, A-Z or '-': use register 0 */
  377.     i = 0;
  378.     y_current = &(y_regs[i]);
  379.     if (writing)    /* remember the register we write into for do_put() */
  380.     y_previous = y_current;
  381. }
  382.  
  383. /*
  384.  * return TRUE if the current yank register has type MLINE
  385.  */
  386.     int
  387. yank_register_mline(regname)
  388.     int        regname;
  389. {
  390.     if (regname != 0 && !valid_yank_reg(regname, FALSE))
  391.     return FALSE;
  392.     get_yank_register(regname, FALSE);
  393.     return (y_current->y_type == MLINE);
  394. }
  395.  
  396. /*
  397.  * start or stop recording into a yank register
  398.  *
  399.  * return FAIL for failure, OK otherwise
  400.  */
  401.     int
  402. do_record(c)
  403.     int c;
  404. {
  405.     char_u    *p;
  406.     static int    regname;
  407.     struct yankreg *old_y_previous, *old_y_current;
  408.     int        retval;
  409.  
  410.     if (Recording == FALSE)        /* start recording */
  411.     {
  412.             /* registers 0-9, a-z and " are allowed */
  413.     if (c > '~' || (!isalnum(c) && c != '"'))
  414.         retval = FAIL;
  415.     else
  416.     {
  417.         Recording = TRUE;
  418.         showmode();
  419.         regname = c;
  420.         retval = OK;
  421.     }
  422.     }
  423.     else                /* stop recording */
  424.     {
  425.     Recording = FALSE;
  426.     MSG("");
  427.     p = get_recorded();
  428.     if (p == NULL)
  429.         retval = FAIL;
  430.     else
  431.     {
  432.         /*
  433.          * We don't want to change the default register here, so save and
  434.          * restore the current register name.
  435.          */
  436.         old_y_previous = y_previous;
  437.         old_y_current = y_current;
  438.  
  439.         retval = stuff_yank(regname, p);
  440.  
  441.         y_previous = old_y_previous;
  442.         y_current = old_y_current;
  443.     }
  444.     }
  445.     return retval;
  446. }
  447.  
  448. /*
  449.  * Stuff string 'p' into yank register 'regname' as a single line (append if
  450.  * uppercase).    'p' must have been alloced.
  451.  *
  452.  * return FAIL for failure, OK otherwise
  453.  */
  454.     static int
  455. stuff_yank(regname, p)
  456.     int        regname;
  457.     char_u  *p;
  458. {
  459.     char_u *lp;
  460.     char_u **pp;
  461.  
  462.                         /* check for read-only register */
  463.     if (regname != 0 && !valid_yank_reg(regname, TRUE))
  464.     return FAIL;
  465.     get_yank_register(regname, TRUE);
  466.     if (y_append && y_current->y_array != NULL)
  467.     {
  468.     pp = &(y_current->y_array[y_current->y_size - 1]);
  469.     lp = lalloc((long_u)(STRLEN(*pp) + STRLEN(p) + 1), TRUE);
  470.     if (lp == NULL)
  471.     {
  472.         vim_free(p);
  473.         return FAIL;
  474.     }
  475.     STRCPY(lp, *pp);
  476.     STRCAT(lp, p);
  477.     vim_free(p);
  478.     vim_free(*pp);
  479.     *pp = lp;
  480.     }
  481.     else
  482.     {
  483.     free_yank_all();
  484.     if ((y_current->y_array =
  485.             (char_u **)alloc((unsigned)sizeof(char_u *))) == NULL)
  486.     {
  487.         vim_free(p);
  488.         return FAIL;
  489.     }
  490.     y_current->y_array[0] = p;
  491.     y_current->y_size = 1;
  492.     y_current->y_type = MCHAR;  /* used to be MLINE, why? */
  493.     }
  494.     return OK;
  495. }
  496.  
  497. /*
  498.  * execute a yank register: copy it into the stuff buffer
  499.  *
  500.  * return FAIL for failure, OK otherwise
  501.  */
  502.     int
  503. do_execreg(regname, colon, addcr)
  504.     int        regname;
  505.     int        colon;        /* insert ':' before each line */
  506.     int        addcr;        /* always add '\n' to end of line */
  507. {
  508.     static int    lastc = NUL;
  509.     long    i;
  510.     char_u    *p;
  511.     int        retval;
  512.  
  513.  
  514.     if (regname == '@')            /* repeat previous one */
  515.     regname = lastc;
  516.                     /* check for valid regname */
  517.     if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE))
  518.     return FAIL;
  519.     lastc = regname;
  520.  
  521.     if (regname == ':')            /* use last command line */
  522.     {
  523.     if (last_cmdline == NULL)
  524.     {
  525.         EMSG(e_nolastcmd);
  526.         return FAIL;
  527.     }
  528.     vim_free(new_last_cmdline); /* don't keep the cmdline containing @: */
  529.     new_last_cmdline = NULL;
  530.     retval = put_in_typebuf(last_cmdline, TRUE);
  531.     }
  532. #ifdef WANT_EVAL
  533.     else if (regname == '=')
  534.     {
  535.     p = get_expr_line();
  536.     if (p == NULL)
  537.         return FAIL;
  538.     retval = put_in_typebuf(p, colon);
  539.     vim_free(p);
  540.     return retval;
  541.     }
  542. #endif
  543.     else if (regname == '.')        /* use last inserted text */
  544.     {
  545.     p = get_last_insert_save();
  546.     if (p == NULL)
  547.     {
  548.         EMSG(e_noinstext);
  549.         return FAIL;
  550.     }
  551.     retval = put_in_typebuf(p, colon);
  552.     vim_free(p);
  553.     return retval;
  554.     }
  555.     else
  556.     {
  557.     get_yank_register(regname, FALSE);
  558.     if (y_current->y_array == NULL)
  559.         return FAIL;
  560.  
  561.     /*
  562.      * Insert lines into typeahead buffer, from last one to first one.
  563.      */
  564.     for (i = y_current->y_size; --i >= 0; )
  565.     {
  566.     /* insert newline between lines and after last line if type is MLINE */
  567.         if (y_current->y_type == MLINE || i < y_current->y_size - 1
  568.                                      || addcr)
  569.         {
  570.         if (ins_typebuf((char_u *)"\n", FALSE, 0, TRUE) == FAIL)
  571.             return FAIL;
  572.         }
  573.         if (ins_typebuf(y_current->y_array[i], FALSE, 0, TRUE) == FAIL)
  574.         return FAIL;
  575.         if (colon && ins_typebuf((char_u *)":", FALSE, 0, TRUE) == FAIL)
  576.         return FAIL;
  577.     }
  578.     Exec_reg = TRUE;    /* disable the 'q' command */
  579.     }
  580.     return OK;
  581. }
  582.  
  583.     static int
  584. put_in_typebuf(s, colon)
  585.     char_u    *s;
  586.     int        colon;        /* add ':' before the line */
  587. {
  588.     int        retval = OK;
  589.  
  590.     if (colon)
  591.     retval = ins_typebuf((char_u *)"\n", FALSE, 0, TRUE);
  592.     if (retval == OK)
  593.     retval = ins_typebuf(s, FALSE, 0, TRUE);
  594.     if (colon && retval == OK)
  595.     retval = ins_typebuf((char_u *)":", FALSE, 0, TRUE);
  596.     return retval;
  597. }
  598.  
  599. /*
  600.  * Insert a yank register: copy it into the Read buffer.
  601.  * Used by CTRL-R command and middle mouse button in insert mode.
  602.  *
  603.  * return FAIL for failure, OK otherwise
  604.  */
  605.     int
  606. insert_reg(regname, literally)
  607.     int regname;
  608.     int literally;    /* insert literally, not as if typed */
  609. {
  610.     long    i;
  611.     int        retval = OK;
  612.     char_u  *arg;
  613.     int        allocated;
  614.  
  615.     /*
  616.      * It is possible to get into an endless loop by having CTRL-R a in
  617.      * register a and then, in insert mode, doing CTRL-R a.
  618.      * If you hit CTRL-C, the loop will be broken here.
  619.      */
  620.     ui_breakcheck();
  621.     if (got_int)
  622.     return FAIL;
  623.  
  624.     /* check for valid regname */
  625.     if (regname != NUL && !valid_yank_reg(regname, FALSE))
  626.     return FAIL;
  627.  
  628. #ifdef USE_CLIPBOARD
  629.     if (regname == '*')
  630.     clip_get_selection();        /* may fill * register */
  631. #endif
  632.  
  633.     if (regname == '.')            /* insert last inserted text */
  634.     retval = stuff_inserted(NUL, 1L, TRUE);
  635.     else if (get_spec_reg(regname, &arg, &allocated))
  636.     {
  637.     if (arg == NULL)
  638.         return FAIL;
  639.     if (literally)
  640.         stuffescaped(arg);
  641.     else
  642.         stuffReadbuff(arg);
  643.     if (allocated)
  644.         vim_free(arg);
  645.     }
  646.     else                /* name or number register */
  647.     {
  648.     get_yank_register(regname, FALSE);
  649.     if (y_current->y_array == NULL)
  650.         retval = FAIL;
  651.     else
  652.     {
  653.         for (i = 0; i < y_current->y_size; ++i)
  654.         {
  655.         if (literally)
  656.             stuffescaped(y_current->y_array[i]);
  657.         else
  658.             stuffReadbuff(y_current->y_array[i]);
  659.         /*
  660.          * Insert a newline between lines and after last line if
  661.          * y_type is MLINE.
  662.          */
  663.         if (y_current->y_type == MLINE || i < y_current->y_size - 1)
  664.             stuffcharReadbuff('\n');
  665.         }
  666.     }
  667.     }
  668.  
  669.     return retval;
  670. }
  671.  
  672. /*
  673.  * Stuff a string into the typeahead buffer, such that edit() will insert it
  674.  * literally.
  675.  */
  676.     static void
  677. stuffescaped(arg)
  678.     char_u    *arg;
  679. {
  680.     while (*arg)
  681.     {
  682.     if ((*arg < ' ' && *arg != TAB) || *arg > '~')
  683.         stuffcharReadbuff(Ctrl('V'));
  684.     stuffcharReadbuff(*arg++);
  685.     }
  686. }
  687.  
  688. /*
  689.  * If "regname" is a special register, return a pointer to its value.
  690.  */
  691.     static int
  692. get_spec_reg(regname, argp, allocated)
  693.     int        regname;
  694.     char_u  **argp;
  695.     int        *allocated;
  696. {
  697.     *argp = NULL;
  698.     *allocated = FALSE;
  699.     if (regname == '%')        /* file name */
  700.     {
  701.     if (check_fname() != FAIL)  /* will give emsg if not set */
  702.         *argp = curbuf->b_fname;
  703.     return TRUE;
  704.     }
  705.     if (regname == '#')        /* alternate file name */
  706.     {
  707.     *argp = getaltfname();    /* will give emsg if not set */
  708.     return TRUE;
  709.     }
  710. #ifdef WANT_EVAL
  711.     if (regname == '=')        /* result of expression */
  712.     {
  713.     *argp = get_expr_line();
  714.     *allocated = TRUE;
  715.     return TRUE;
  716.     }
  717. #endif
  718.     if (regname == ':')        /* last command line */
  719.     {
  720.     if (last_cmdline == NULL)
  721.         EMSG(e_nolastcmd);
  722.     else
  723.         *argp = last_cmdline;
  724.     return TRUE;
  725.     }
  726.     if (regname == '.')        /* last inserted text */
  727.     {
  728.     *argp = get_last_insert_save();
  729.     *allocated = TRUE;
  730.     if (*argp == NULL)
  731.         EMSG(e_noinstext);
  732.     return TRUE;
  733.     }
  734.  
  735.     return FALSE;
  736. }
  737.  
  738. /*
  739.  * paste a yank register into the command line.
  740.  * used by CTRL-R command in command-line mode
  741.  * insert_reg() can't be used here, because special characters from the
  742.  * register contents will be interpreted as commands.
  743.  *
  744.  * return FAIL for failure, OK otherwise
  745.  */
  746.     int
  747. cmdline_paste(regname)
  748.     int regname;
  749. {
  750.     long    i;
  751.     char_u    *arg;
  752.     int        allocated;
  753.  
  754.     if (!valid_yank_reg(regname, FALSE))    /* check for valid regname */
  755.     return FAIL;
  756.  
  757. #ifdef USE_CLIPBOARD
  758.     if (regname == '*')
  759.     clip_get_selection();
  760. #endif
  761.  
  762.     if (regname == '.')            /* insert last inserted text */
  763.     return FAIL;            /* Unimplemented */
  764.  
  765.     if (get_spec_reg(regname, &arg, &allocated))
  766.     {
  767.     if (arg == NULL)
  768.         return FAIL;
  769.     i = put_on_cmdline(arg, -1, TRUE);
  770.     if (allocated)
  771.         vim_free(arg);
  772.     return (int)i;
  773.     }
  774.  
  775.     get_yank_register(regname, FALSE);
  776.     if (y_current->y_array == NULL)
  777.     return FAIL;
  778.  
  779.     for (i = 0; i < y_current->y_size; ++i)
  780.     {
  781.     put_on_cmdline(y_current->y_array[i], -1, FALSE);
  782.  
  783.     /* insert ^M between lines and after last line if type is MLINE */
  784.     if (y_current->y_type == MLINE || i < y_current->y_size - 1)
  785.         put_on_cmdline((char_u *)"\r", 1, FALSE);
  786.     }
  787.     return OK;
  788. }
  789.  
  790. /*
  791.  * op_delete - handle a delete operation
  792.  *
  793.  * return FAIL if undo failed, OK otherwise.
  794.  */
  795.     int
  796. op_delete(oap)
  797.     OPARG   *oap;
  798. {
  799.     int            n;
  800.     linenr_t        lnum;
  801.     char_u        *ptr;
  802.     char_u        *newp, *oldp;
  803.     linenr_t        old_lcount = curbuf->b_ml.ml_line_count;
  804.     int            did_yank = FALSE;
  805.     struct block_def    bd;
  806.  
  807.     if (curbuf->b_ml.ml_flags & ML_EMPTY)        /* nothing to do */
  808.     return OK;
  809.  
  810.     /* Nothing to delete, return here.    Do prepare undo, for op_change(). */
  811.     if (oap->empty)
  812.     {
  813.     return u_save_cursor();
  814.     }
  815.  
  816. /*
  817.  * Imitate the strange Vi behaviour: If the delete spans more than one line
  818.  * and motion_type == MCHAR and the result is a blank line, make the delete
  819.  * linewise.  Don't do this for the change command or Visual mode.
  820.  */
  821.     if (       oap->motion_type == MCHAR
  822.         && !oap->is_VIsual
  823.         && oap->line_count > 1
  824.         && oap->op_type == OP_DELETE)
  825.     {
  826.     ptr = ml_get(oap->end.lnum) + oap->end.col + oap->inclusive;
  827.     ptr = skipwhite(ptr);
  828.     if (*ptr == NUL && inindent(0))
  829.         oap->motion_type = MLINE;
  830.     }
  831.  
  832. /*
  833.  * Check for trying to delete (e.g. "D") in an empty line.
  834.  * Note: For the change operator it is ok.
  835.  */
  836.     if (       oap->motion_type == MCHAR
  837.         && oap->line_count == 1
  838.         && oap->op_type == OP_DELETE
  839.         && *ml_get(oap->start.lnum) == NUL)
  840.     {
  841.     /*
  842.      * It's an error to operate on an empty region, when 'E' inclucded in
  843.      * 'cpoptions' (Vi compatible).
  844.      */
  845.     if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL)
  846.         beep_flush();
  847.     return OK;
  848.     }
  849.  
  850. /*
  851.  * Do a yank of whatever we're about to delete.
  852.  * If a yank register was specified, put the deleted text into that register
  853.  */
  854.     if (oap->regname != 0)
  855.     {
  856.                     /* check for read-only register */
  857.     if (!valid_yank_reg(oap->regname, TRUE))
  858.     {
  859.         beep_flush();
  860.         return OK;
  861.     }
  862.     get_yank_register(oap->regname, TRUE);    /* yank into specified reg. */
  863.     if (op_yank(oap, TRUE, FALSE) == OK)    /* yank without message */
  864.         did_yank = TRUE;
  865.     }
  866.  
  867. /*
  868.  * Put deleted text into register 1 and shift number registers if
  869.  * the delete contains a line break, or when a regname has been specified!
  870.  */
  871.     if (oap->regname != 0 || oap->motion_type == MLINE || oap->line_count > 1)
  872.     {
  873.     y_current = &y_regs[9];
  874.     free_yank_all();        /* free register nine */
  875.     for (n = 9; n > 1; --n)
  876.         y_regs[n] = y_regs[n - 1];
  877.     y_previous = y_current = &y_regs[1];
  878.     y_regs[1].y_array = NULL;    /* set register one to empty */
  879.     oap->regname = 0;
  880.     }
  881.     else if (oap->regname == 0)        /* yank into unnamed register */
  882.     {
  883.     oap->regname = '-';        /* use special delete register */
  884.     get_yank_register(oap->regname, TRUE);
  885.     oap->regname = 0;
  886.     }
  887.  
  888.     if (oap->regname == 0 && op_yank(oap, TRUE, FALSE) == OK)
  889.     did_yank = TRUE;
  890.  
  891. /*
  892.  * If there's too much stuff to fit in the yank register, then get a
  893.  * confirmation before doing the delete. This is crude, but simple. And it
  894.  * avoids doing a delete of something we can't put back if we want.
  895.  */
  896.     if (!did_yank)
  897.     {
  898.     if (ask_yesno((char_u *)"cannot yank; delete anyway", TRUE) != 'y')
  899.     {
  900.         emsg(e_abort);
  901.         return FAIL;
  902.     }
  903.     }
  904.  
  905. /*
  906.  * block mode delete
  907.  */
  908.     if (oap->block_mode)
  909.     {
  910.     if (u_save((linenr_t)(oap->start.lnum - 1),
  911.                    (linenr_t)(oap->end.lnum + 1)) == FAIL)
  912.         return FAIL;
  913.  
  914.     for (lnum = curwin->w_cursor.lnum;
  915.                    curwin->w_cursor.lnum <= oap->end.lnum;
  916.                               ++curwin->w_cursor.lnum)
  917.     {
  918.         block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
  919.         if (bd.textlen == 0)    /* nothing to delete */
  920.         continue;
  921.  
  922.         /* n == number of chars deleted
  923.          * If we delete a TAB, it may be replaced by several characters.
  924.          * Thus the number of characters may increase!
  925.          */
  926.         n = bd.textlen - bd.startspaces - bd.endspaces;
  927.         oldp = ml_get_curline();
  928.         newp = alloc_check((unsigned)STRLEN(oldp) + 1 - n);
  929.         if (newp == NULL)
  930.         continue;
  931.         /* copy up to deleted part */
  932.         vim_memmove(newp, oldp, (size_t)bd.textcol);
  933.         /* insert spaces */
  934.         copy_spaces(newp + bd.textcol,
  935.                      (size_t)(bd.startspaces + bd.endspaces));
  936.         /* copy the part after the deleted part */
  937.         oldp += bd.textcol + bd.textlen;
  938.         vim_memmove(newp + bd.textcol + bd.startspaces + bd.endspaces,
  939.                               oldp, STRLEN(oldp) + 1);
  940.         /* replace the line */
  941.         ml_replace(curwin->w_cursor.lnum, newp, FALSE);
  942.     }
  943.  
  944.     curwin->w_cursor.lnum = lnum;
  945.     changed_cline_bef_curs();    /* recompute cursor pos. on screen */
  946.     approximate_botline();        /* w_botline may be wrong now */
  947.     adjust_cursor();
  948.  
  949.     CHANGED;
  950.     update_screen(VALID_TO_CURSCHAR);
  951.     oap->line_count = 0;        /* no lines deleted */
  952.     }
  953.     else if (oap->motion_type == MLINE)
  954.     {
  955.     if (oap->op_type == OP_CHANGE)
  956.     {
  957.         /* Delete the lines except the first one.  Temporarily move the
  958.          * cursor to the next line.  Save the current line number, if the
  959.          * last line is deleted it may be changed.
  960.          */
  961.         if (oap->line_count > 1)
  962.         {
  963.         lnum = curwin->w_cursor.lnum;
  964.         ++curwin->w_cursor.lnum;
  965.         del_lines((long)(oap->line_count - 1), TRUE, TRUE);
  966.         curwin->w_cursor.lnum = lnum;
  967.         }
  968.         if (u_save_cursor() == FAIL)
  969.         return FAIL;
  970.         if (curbuf->b_p_ai)            /* don't delete indent */
  971.         {
  972.         beginline(BL_WHITE);        /* cursor on first non-white */
  973.         did_ai = TRUE;            /* delete the indent when ESC hit */
  974.         }
  975.         else
  976.         beginline(0);            /* cursor in column 0 */
  977.         truncate_line(FALSE);   /* delete the rest of the line */
  978.                     /* leave cursor past last char in line */
  979.     }
  980.     else
  981.     {
  982.         del_lines(oap->line_count, TRUE, TRUE);
  983.         beginline(BL_WHITE | BL_FIX);
  984.     }
  985.     u_clearline();    /* "U" command should not be possible after "dd" */
  986.     }
  987.     else if (oap->line_count == 1)    /* delete characters within one line */
  988.     {
  989.     if (u_save_cursor() == FAIL)
  990.         return FAIL;
  991.         /* if 'cpoptions' contains '$', display '$' at end of change */
  992.     if (       vim_strchr(p_cpo, CPO_DOLLAR) != NULL
  993.         && oap->op_type == OP_CHANGE
  994.         && oap->end.lnum == curwin->w_cursor.lnum
  995.         && !oap->is_VIsual)
  996.         display_dollar(oap->end.col - !oap->inclusive);
  997.     n = oap->end.col - oap->start.col + 1 - !oap->inclusive;
  998.     (void)del_chars((long)n, TRUE);
  999.     }
  1000.     else                /* delete characters between lines */
  1001.     {
  1002.     if (u_save_cursor() == FAIL)    /* save first line for undo */
  1003.         return FAIL;
  1004.     truncate_line(TRUE);        /* delete from cursor to end of line */
  1005.  
  1006.     oap->start = curwin->w_cursor;    /* remember curwin->w_cursor */
  1007.     ++curwin->w_cursor.lnum;
  1008.                     /* includes save for undo */
  1009.     del_lines((long)(oap->line_count - 2), TRUE, TRUE);
  1010.  
  1011.     if (u_save_cursor() == FAIL)    /* save last line for undo */
  1012.         return FAIL;
  1013.     /* delete from start of line until op_end */
  1014.     curwin->w_cursor.col = 0;
  1015.     (void)del_chars((long)(oap->end.col + 1 - !oap->inclusive), TRUE);
  1016.     curwin->w_cursor = oap->start;    /* restore curwin->w_cursor */
  1017.     (void)do_join(FALSE, TRUE);
  1018.     }
  1019.  
  1020.     /*
  1021.      * For a change within one line, the screen is updated differently (to
  1022.      * take care of 'dollar').
  1023.      */
  1024.     if (oap->motion_type == MCHAR && oap->line_count == 1)
  1025.     {
  1026.     if (dollar_vcol)
  1027.         must_redraw = 0;        /* don't want a redraw now */
  1028.     else
  1029.         update_screenline();
  1030.     }
  1031.     else if (!global_busy)        /* no need to update screen for :global */
  1032.     {
  1033.     update_topline();
  1034.     update_screen(NOT_VALID);
  1035.     }
  1036.  
  1037.     msgmore(curbuf->b_ml.ml_line_count - old_lcount);
  1038.  
  1039.     /*
  1040.      * Set "'[" and "']" marks.
  1041.      */
  1042.     curbuf->b_op_start = oap->start;
  1043.     if (oap->block_mode)
  1044.     {
  1045.     curbuf->b_op_end.lnum = oap->end.lnum;
  1046.     curbuf->b_op_end.col = oap->start.col;
  1047.     }
  1048.     else
  1049.     curbuf->b_op_end = oap->start;
  1050.  
  1051.     return OK;
  1052. }
  1053.  
  1054. /*
  1055.  * op_tilde - handle the (non-standard vi) tilde operator
  1056.  */
  1057.     void
  1058. op_tilde(oap)
  1059.     OPARG    *oap;
  1060. {
  1061.     FPOS        pos;
  1062.     struct block_def    bd;
  1063.  
  1064.     if (u_save((linenr_t)(oap->start.lnum - 1),
  1065.                        (linenr_t)(oap->end.lnum + 1)) == FAIL)
  1066.     return;
  1067.  
  1068.     /*
  1069.      * Set '[ and '] marks.
  1070.      */
  1071.     curbuf->b_op_start = oap->start;
  1072.     curbuf->b_op_end = oap->end;
  1073.  
  1074.     pos = oap->start;
  1075.     if (oap->block_mode)            /* Visual block mode */
  1076.     {
  1077.     for (; pos.lnum <= oap->end.lnum; ++pos.lnum)
  1078.     {
  1079.         block_prep(oap, &bd, pos.lnum, FALSE);
  1080.         pos.col = bd.textcol;
  1081.         while (--bd.textlen >= 0)
  1082.         {
  1083.         swapchar(oap->op_type, &pos);
  1084.         if (inc(&pos) == -1)        /* at end of file */
  1085.             break;
  1086.         }
  1087.     }
  1088.     }
  1089.     else                    /* not block mode */
  1090.     {
  1091.     if (oap->motion_type == MLINE)
  1092.     {
  1093.         pos.col = 0;
  1094.         oap->end.col = STRLEN(ml_get(oap->end.lnum));
  1095.         if (oap->end.col)
  1096.         --oap->end.col;
  1097.     }
  1098.     else if (!oap->inclusive)
  1099.         dec(&(oap->end));
  1100.  
  1101.     while (ltoreq(pos, oap->end))
  1102.     {
  1103.         swapchar(oap->op_type, &pos);
  1104.         if (inc(&pos) == -1)    /* at end of file */
  1105.         break;
  1106.     }
  1107.     }
  1108.  
  1109.     if (oap->motion_type == MCHAR && oap->line_count == 1 && !oap->block_mode)
  1110.     update_screenline();
  1111.     else
  1112.     {
  1113.     update_topline();
  1114.     update_screen(NOT_VALID);
  1115.     }
  1116.  
  1117.     if (oap->line_count > p_report)
  1118.     smsg((char_u *)"%ld line%s ~ed",
  1119.                     oap->line_count, plural(oap->line_count));
  1120. }
  1121.  
  1122. /*
  1123.  * If op_type == OP_UPPER: make uppercase,
  1124.  * if op_type == OP_LOWER: make lowercase,
  1125.  * else swap case of character at 'pos'
  1126.  */
  1127.     void
  1128. swapchar(op_type, pos)
  1129.     int        op_type;
  1130.     FPOS    *pos;
  1131. {
  1132.     int        c;
  1133.  
  1134.     c = gchar(pos);
  1135.     if (islower(c) && op_type != OP_LOWER)
  1136.     {
  1137.     pchar(*pos, TO_UPPER(c));
  1138.     CHANGED;
  1139.     }
  1140.     else if (isupper(c) && op_type != OP_UPPER)
  1141.     {
  1142.     pchar(*pos, TO_LOWER(c));
  1143.     CHANGED;
  1144.     }
  1145. }
  1146.  
  1147. /*
  1148.  * op_change - handle a change operation
  1149.  *
  1150.  * return TRUE if edit() returns because of a CTRL-O command
  1151.  */
  1152.     int
  1153. op_change(oap)
  1154.     OPARG    *oap;
  1155. {
  1156.     colnr_t           l;
  1157.  
  1158.     l = oap->start.col;
  1159.     if (oap->motion_type == MLINE)
  1160.     {
  1161.     l = 0;
  1162. #ifdef SMARTINDENT
  1163.     if (curbuf->b_p_si)
  1164.         can_si = TRUE;    /* It's like opening a new line, do si */
  1165. #endif
  1166.     }
  1167.  
  1168.     /* First delete the text in the region.  In an empty buffer only need to
  1169.      * save for undo */
  1170.     if (curbuf->b_ml.ml_flags & ML_EMPTY)
  1171.     {
  1172.     if (u_save_cursor() == FAIL)
  1173.         return FALSE;
  1174.     }
  1175.     else if (op_delete(oap) == FAIL)
  1176.     return FALSE;
  1177.  
  1178.     if ((l > curwin->w_cursor.col) && !lineempty(curwin->w_cursor.lnum))
  1179.     inc_cursor();
  1180.  
  1181. #if defined(LISPINDENT) || defined(CINDENT)
  1182.     if (oap->motion_type == MLINE)
  1183.     {
  1184. # ifdef LISPINDENT
  1185.     if (curbuf->b_p_lisp && curbuf->b_p_ai)
  1186.         fixthisline(get_lisp_indent);
  1187. # endif
  1188. # if defined(LISPINDENT) && defined(CINDENT)
  1189.     else
  1190. # endif
  1191. # ifdef CINDENT
  1192.     if (curbuf->b_p_cin)
  1193.         fixthisline(get_c_indent);
  1194. # endif
  1195.     }
  1196. #endif
  1197.  
  1198.     return edit(NUL, FALSE, (linenr_t)1);
  1199. }
  1200.  
  1201. /*
  1202.  * set all the yank registers to empty (called from main())
  1203.  */
  1204.     void
  1205. init_yank()
  1206. {
  1207.     int        i;
  1208.  
  1209.     for (i = 0; i < NUM_REGISTERS; ++i)
  1210.     y_regs[i].y_array = NULL;
  1211. }
  1212.  
  1213. /*
  1214.  * Free "n" lines from the current yank register.
  1215.  * Called for normal freeing and in case of error.
  1216.  */
  1217.     static void
  1218. free_yank(n)
  1219.     long n;
  1220. {
  1221.     if (y_current->y_array != NULL)
  1222.     {
  1223.     long        i;
  1224.  
  1225.     for (i = n; --i >= 0; )
  1226.     {
  1227.         if ((i & 1023) == 1023)            /* this may take a while */
  1228.         {
  1229.         /*
  1230.          * This message should never cause a hit-return message.
  1231.          * Overwrite this message with any next message.
  1232.          */
  1233.         ++no_wait_return;
  1234.         smsg((char_u *)"freeing %ld lines", i + 1);
  1235.         --no_wait_return;
  1236.         msg_didout = FALSE;
  1237.         msg_col = 0;
  1238.         }
  1239.         vim_free(y_current->y_array[i]);
  1240.     }
  1241.     vim_free(y_current->y_array);
  1242.     y_current->y_array = NULL;
  1243.     if (n >= 1000)
  1244.         MSG("");
  1245.     }
  1246. }
  1247.  
  1248.     static void
  1249. free_yank_all()
  1250. {
  1251.     free_yank(y_current->y_size);
  1252. }
  1253.  
  1254. /*
  1255.  * Yank the text between curwin->w_cursor and startpos into a yank register.
  1256.  * If we are to append (uppercase register), we first yank into a new yank
  1257.  * register and then concatenate the old and the new one (so we keep the old
  1258.  * one in case of out-of-memory).
  1259.  *
  1260.  * return FAIL for failure, OK otherwise
  1261.  */
  1262.     int
  1263. op_yank(oap, deleting, mess)
  1264.     OPARG   *oap;
  1265.     int        deleting;
  1266.     int        mess;
  1267. {
  1268.     long        y_idx;        /* index in y_array[] */
  1269.     struct yankreg    *curr;        /* copy of y_current */
  1270.     struct yankreg    newreg;        /* new yank register when appending */
  1271.     char_u        **new_ptr;
  1272.     linenr_t        lnum;        /* current line number */
  1273.     long        j;
  1274.     long        len;
  1275.     int            yanktype = oap->motion_type;
  1276.     long        yanklines = oap->line_count;
  1277.     linenr_t        yankendlnum = oap->end.lnum;
  1278.     char_u        *p;
  1279.     char_u        *pnew;
  1280.     struct block_def    bd;
  1281.  
  1282.                     /* check for read-only register */
  1283.     if (oap->regname != 0 && !valid_yank_reg(oap->regname, TRUE))
  1284.     {
  1285.     beep_flush();
  1286.     return FAIL;
  1287.     }
  1288.     if (!deleting)            /* op_delete() already set y_current */
  1289.     get_yank_register(oap->regname, TRUE);
  1290.  
  1291.     curr = y_current;
  1292.                     /* append to existing contents */
  1293.     if (y_append && y_current->y_array != NULL)
  1294.     y_current = &newreg;
  1295.     else
  1296.     free_yank_all();        /* free previously yanked lines */
  1297.  
  1298. /*
  1299.  * If the cursor was in column 1 before and after the movement, and the
  1300.  * operator is not inclusive, the yank is always linewise.
  1301.  */
  1302.     if (       oap->motion_type == MCHAR
  1303.         && oap->start.col == 0
  1304.         && !oap->inclusive
  1305.         && oap->end.col == 0
  1306.         && yanklines > 1)
  1307.     {
  1308.     yanktype = MLINE;
  1309.     --yankendlnum;
  1310.     --yanklines;
  1311.     }
  1312.  
  1313.     y_current->y_size = yanklines;
  1314.     y_current->y_type = yanktype;   /* set the yank register type */
  1315.     y_current->y_array = (char_u **)lalloc_clear((long_u)(sizeof(char_u *) *
  1316.                                 yanklines), TRUE);
  1317.  
  1318.     if (y_current->y_array == NULL)
  1319.     {
  1320.     y_current = curr;
  1321.     return FAIL;
  1322.     }
  1323.  
  1324.     y_idx = 0;
  1325.     lnum = oap->start.lnum;
  1326.  
  1327. /*
  1328.  * Visual block mode
  1329.  */
  1330.     if (oap->block_mode)
  1331.     {
  1332.     y_current->y_type = MBLOCK;        /* set the yank register type */
  1333.     for ( ; lnum <= yankendlnum; ++lnum)
  1334.     {
  1335.         block_prep(oap, &bd, lnum, FALSE);
  1336.  
  1337.         if ((pnew = alloc(bd.startspaces + bd.endspaces +
  1338.                       bd.textlen + 1)) == NULL)
  1339.         goto fail;
  1340.         y_current->y_array[y_idx++] = pnew;
  1341.  
  1342.         copy_spaces(pnew, (size_t)bd.startspaces);
  1343.         pnew += bd.startspaces;
  1344.  
  1345.         vim_memmove(pnew, bd.textstart, (size_t)bd.textlen);
  1346.         pnew += bd.textlen;
  1347.  
  1348.         copy_spaces(pnew, (size_t)bd.endspaces);
  1349.         pnew += bd.endspaces;
  1350.  
  1351.         *pnew = NUL;
  1352.     }
  1353.     }
  1354.     else
  1355.     {
  1356.     /*
  1357.      * there are three parts for non-block mode:
  1358.      * 1. if yanktype != MLINE yank last part of the top line
  1359.      * 2. yank the lines between op_start and op_end, inclusive when
  1360.      *    yanktype == MLINE
  1361.      * 3. if yanktype != MLINE yank first part of the bot line
  1362.      */
  1363.     if (yanktype != MLINE)
  1364.     {
  1365.         if (yanklines == 1)        /* op_start and op_end on same line */
  1366.         {
  1367.         j = oap->end.col - oap->start.col + 1 - !oap->inclusive;
  1368.         /* Watch out for very big endcol (MAXCOL) */
  1369.         p = ml_get(lnum) + oap->start.col;
  1370.         len = STRLEN(p);
  1371.         if (j > len || j < 0)
  1372.             j = len;
  1373.         if ((y_current->y_array[0] = vim_strnsave(p, (int)j)) == NULL)
  1374.         {
  1375. fail:
  1376.             free_yank(y_idx);    /* free the allocated lines */
  1377.             y_current = curr;
  1378.             return FAIL;
  1379.         }
  1380.         goto success;
  1381.         }
  1382.         if ((y_current->y_array[0] =
  1383.             vim_strsave(ml_get(lnum++) + oap->start.col)) == NULL)
  1384.         goto fail;
  1385.         ++y_idx;
  1386.     }
  1387.  
  1388.     while (yanktype == MLINE ? (lnum <= yankendlnum) : (lnum < yankendlnum))
  1389.     {
  1390.         if ((y_current->y_array[y_idx] =
  1391.                      vim_strsave(ml_get(lnum++))) == NULL)
  1392.         goto fail;
  1393.         ++y_idx;
  1394.     }
  1395.     if (yanktype != MLINE)
  1396.     {
  1397.         if ((y_current->y_array[y_idx] = vim_strnsave(ml_get(yankendlnum),
  1398.                  oap->end.col + 1 - !oap->inclusive)) == NULL)
  1399.         goto fail;
  1400.     }
  1401.     }
  1402.  
  1403. success:
  1404.     if (curr != y_current)    /* append the new block to the old block */
  1405.     {
  1406.     new_ptr = (char_u **)lalloc((long_u)(sizeof(char_u *) *
  1407.                    (curr->y_size + y_current->y_size)), TRUE);
  1408.     if (new_ptr == NULL)
  1409.         goto fail;
  1410.     for (j = 0; j < curr->y_size; ++j)
  1411.         new_ptr[j] = curr->y_array[j];
  1412.     vim_free(curr->y_array);
  1413.     curr->y_array = new_ptr;
  1414.  
  1415.     if (yanktype == MLINE)    /* MLINE overrides MCHAR and MBLOCK */
  1416.         curr->y_type = MLINE;
  1417.  
  1418.     /* concatenate the last line of the old block with the first line of
  1419.      * the new block */
  1420.     if (curr->y_type == MCHAR)
  1421.     {
  1422.         pnew = lalloc((long_u)(STRLEN(curr->y_array[curr->y_size - 1])
  1423.                   + STRLEN(y_current->y_array[0]) + 1), TRUE);
  1424.         if (pnew == NULL)
  1425.         {
  1426.             y_idx = y_current->y_size - 1;
  1427.             goto fail;
  1428.         }
  1429.         STRCPY(pnew, curr->y_array[--j]);
  1430.         STRCAT(pnew, y_current->y_array[0]);
  1431.         vim_free(curr->y_array[j]);
  1432.         vim_free(y_current->y_array[0]);
  1433.         curr->y_array[j++] = pnew;
  1434.         y_idx = 1;
  1435.     }
  1436.     else
  1437.         y_idx = 0;
  1438.     while (y_idx < y_current->y_size)
  1439.         curr->y_array[j++] = y_current->y_array[y_idx++];
  1440.     curr->y_size = j;
  1441.     vim_free(y_current->y_array);
  1442.     y_current = curr;
  1443.     }
  1444.     if (mess)            /* Display message about yank? */
  1445.     {
  1446.     if (yanktype == MCHAR && !oap->block_mode && yanklines == 1)
  1447.         yanklines = 0;
  1448.     /* Some versions of Vi use ">=" here, some don't...  */
  1449.     if (yanklines > p_report)
  1450.     {
  1451.         /* redisplay now, so message is not deleted */
  1452.         update_topline_redraw();
  1453.         smsg((char_u *)"%ld line%s yanked", yanklines, plural(yanklines));
  1454.     }
  1455.     }
  1456.  
  1457.     /*
  1458.      * Set "'[" and "']" marks.
  1459.      */
  1460.     curbuf->b_op_start = oap->start;
  1461.     curbuf->b_op_end = oap->end;
  1462.  
  1463. #ifdef USE_CLIPBOARD
  1464.     /*
  1465.      * If we were yanking to the clipboard register, send result to clipboard.
  1466.      */
  1467.     if (curr == &(y_regs[CLIPBOARD_REGISTER]))
  1468.     {
  1469.     clip_own_selection();
  1470.     clip_mch_set_selection();
  1471.     }
  1472. #endif
  1473.  
  1474.     return OK;
  1475. }
  1476.  
  1477. /*
  1478.  * put contents of register "regname" into the text
  1479.  * For ":put" command count == -1.
  1480.  */
  1481.     void
  1482. do_put(regname, dir, count, fix_indent)
  1483.     int        regname;
  1484.     int        dir;        /* BACKWARD for 'P', FORWARD for 'p' */
  1485.     long    count;
  1486.     int        fix_indent;        /* make indent look nice */
  1487. {
  1488.     char_u    *ptr;
  1489.     char_u    *newp, *oldp;
  1490.     int        yanklen;
  1491.     int        oldlen;
  1492.     int        totlen = 0;            /* init for gcc */
  1493.     linenr_t    lnum;
  1494.     colnr_t    col;
  1495.     long    i;                /* index in y_array[] */
  1496.     int        y_type;
  1497.     long    y_size;
  1498.     char_u    **y_array;
  1499.     long    nr_lines = 0;
  1500.     colnr_t    vcol;
  1501.     int        delcount;
  1502.     int        incr = 0;
  1503.     long    j;
  1504.     FPOS    new_cursor;
  1505.     int        indent;
  1506.     int        orig_indent = 0;        /* init for gcc */
  1507.     int        indent_diff = 0;        /* init for gcc */
  1508.     int        first_indent = TRUE;
  1509.     FPOS    old_pos;
  1510.     struct block_def bd;
  1511.     char_u    *insert_string = NULL;
  1512.     int        allocated = FALSE;
  1513.  
  1514. #ifdef USE_CLIPBOARD
  1515.     if (regname == '*')
  1516.     clip_get_selection();
  1517. #endif
  1518.  
  1519.     if (fix_indent)
  1520.     orig_indent = get_indent();
  1521.  
  1522.     curbuf->b_op_start = curwin->w_cursor;    /* default for '[ mark */
  1523.     if (dir == FORWARD)
  1524.     curbuf->b_op_start.col++;
  1525.     curbuf->b_op_end = curwin->w_cursor;    /* default for '] mark */
  1526.  
  1527.     /*
  1528.      * Using inserted text works differently, because the register includes
  1529.      * special characters (newlines, etc.).
  1530.      */
  1531.     if (regname == '.')
  1532.     {
  1533.     (void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') :
  1534.                     (count == -1 ? 'O' : 'i')), count, FALSE);
  1535.     return;
  1536.     }
  1537.  
  1538.     /*
  1539.      * For special registers '%' (file name), '#' (alternate file name) and
  1540.      * ':' (last command line), etc. we have to create a fake yank register.
  1541.      */
  1542.     if (get_spec_reg(regname, &insert_string, &allocated))
  1543.     {
  1544.     if (insert_string == NULL)
  1545.         return;
  1546.     }
  1547.  
  1548.     if (insert_string != NULL)
  1549.     {
  1550.     y_type = MCHAR;            /* use fake one-line yank register */
  1551.     y_size = 1;
  1552.     y_array = &insert_string;
  1553.     }
  1554.     else
  1555.     {
  1556.     get_yank_register(regname, FALSE);
  1557.  
  1558.     y_type = y_current->y_type;
  1559.     y_size = y_current->y_size;
  1560.     y_array = y_current->y_array;
  1561.     }
  1562.  
  1563.     if (count == -1)        /* :put command */
  1564.     {
  1565.     y_type = MLINE;
  1566.     count = 1;
  1567.     }
  1568.  
  1569.     if (y_size == 0 || y_array == NULL)
  1570.     {
  1571.     EMSG2("Nothing in register %s",
  1572.           regname == 0 ? (char_u *)"\"" : transchar(regname));
  1573.     goto end;
  1574.     }
  1575.  
  1576.     if (y_type == MBLOCK)
  1577.     {
  1578.     lnum = curwin->w_cursor.lnum + y_size + 1;
  1579.     if (lnum > curbuf->b_ml.ml_line_count)
  1580.         lnum = curbuf->b_ml.ml_line_count + 1;
  1581.     if (u_save(curwin->w_cursor.lnum - 1, lnum) == FAIL)
  1582.         goto end;
  1583.     }
  1584.     else if (u_save_cursor() == FAIL)
  1585.     goto end;
  1586.  
  1587.     yanklen = STRLEN(y_array[0]);
  1588.     CHANGED;
  1589.  
  1590.     lnum = curwin->w_cursor.lnum;
  1591.     col = curwin->w_cursor.col;
  1592.     approximate_botline();        /* w_botline might not be valid now */
  1593.     changed_cline_bef_curs();        /* cursor posn on screen may change */
  1594.  
  1595. /*
  1596.  * block mode
  1597.  */
  1598.     if (y_type == MBLOCK)
  1599.     {
  1600.     if (dir == FORWARD && gchar_cursor() != NUL)
  1601.     {
  1602.         getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
  1603.         ++col;
  1604.         ++curwin->w_cursor.col;
  1605.     }
  1606.     else
  1607.         getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
  1608.     for (i = 0; i < y_size; ++i)
  1609.     {
  1610.         bd.startspaces = 0;
  1611.         bd.endspaces = 0;
  1612.         bd.textcol = 0;
  1613.         vcol = 0;
  1614.         delcount = 0;
  1615.  
  1616.     /* add a new line */
  1617.         if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
  1618.         {
  1619.         ml_append(curbuf->b_ml.ml_line_count, (char_u *)"",
  1620.                                (colnr_t)1, FALSE);
  1621.         ++nr_lines;
  1622.         }
  1623.         oldp = ml_get_curline();
  1624.         oldlen = STRLEN(oldp);
  1625.         for (ptr = oldp; vcol < col && *ptr; ++ptr)
  1626.         {
  1627.         /* Count a tab for what it's worth (if list mode not on) */
  1628.         incr = lbr_chartabsize(ptr, (colnr_t)vcol);
  1629.         vcol += incr;
  1630.         ++bd.textcol;
  1631.         }
  1632.         if (vcol < col) /* line too short, padd with spaces */
  1633.         {
  1634.         bd.startspaces = col - vcol;
  1635.         }
  1636.         else if (vcol > col)
  1637.         {
  1638.         bd.endspaces = vcol - col;
  1639.         bd.startspaces = incr - bd.endspaces;
  1640.         --bd.textcol;
  1641.         delcount = 1;
  1642.         }
  1643.         yanklen = STRLEN(y_array[i]);
  1644.         totlen = count * yanklen + bd.startspaces + bd.endspaces;
  1645.         newp = alloc_check((unsigned)totlen + oldlen + 1);
  1646.         if (newp == NULL)
  1647.         break;
  1648.     /* copy part up to cursor to new line */
  1649.         ptr = newp;
  1650.         vim_memmove(ptr, oldp, (size_t)bd.textcol);
  1651.         ptr += bd.textcol;
  1652.     /* may insert some spaces before the new text */
  1653.         copy_spaces(ptr, (size_t)bd.startspaces);
  1654.         ptr += bd.startspaces;
  1655.     /* insert the new text */
  1656.         for (j = 0; j < count; ++j)
  1657.         {
  1658.         vim_memmove(ptr, y_array[i], (size_t)yanklen);
  1659.         ptr += yanklen;
  1660.         }
  1661.     /* may insert some spaces after the new text */
  1662.         copy_spaces(ptr, (size_t)bd.endspaces);
  1663.         ptr += bd.endspaces;
  1664.     /* move the text after the cursor to the end of the line. */
  1665.         vim_memmove(ptr, oldp + bd.textcol + delcount,
  1666.                 (size_t)(oldlen - bd.textcol - delcount + 1));
  1667.         ml_replace(curwin->w_cursor.lnum, newp, FALSE);
  1668.  
  1669.         ++curwin->w_cursor.lnum;
  1670.         if (i == 0)
  1671.         curwin->w_cursor.col += bd.startspaces;
  1672.     }
  1673.                         /* adjust '] mark */
  1674.     curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1;
  1675.     curbuf->b_op_end.col = bd.textcol + totlen - 1;
  1676.     curwin->w_cursor.lnum = lnum;
  1677.     update_topline();
  1678.     update_screen(VALID_TO_CURSCHAR);
  1679.     }
  1680.     else    /* not block mode */
  1681.     {
  1682.     if (y_type == MCHAR)
  1683.     {
  1684.     /* if type is MCHAR, FORWARD is the same as BACKWARD on the next char */
  1685.         if (dir == FORWARD && gchar_cursor() != NUL)
  1686.         {
  1687.         ++col;
  1688.         if (yanklen)
  1689.         {
  1690.             ++curwin->w_cursor.col;
  1691.             ++curbuf->b_op_end.col;
  1692.         }
  1693.         }
  1694.         new_cursor = curwin->w_cursor;
  1695.     }
  1696.     else if (dir == BACKWARD)
  1697.     /* if type is MLINE, BACKWARD is the same as FORWARD on the previous line */
  1698.         --lnum;
  1699.  
  1700. /*
  1701.  * simple case: insert into current line
  1702.  */
  1703.     if (y_type == MCHAR && y_size == 1)
  1704.     {
  1705.         totlen = count * yanklen;
  1706.         if (totlen)
  1707.         {
  1708.         oldp = ml_get(lnum);
  1709.         newp = alloc_check((unsigned)(STRLEN(oldp) + totlen + 1));
  1710.         if (newp == NULL)
  1711.             goto end;        /* alloc() will give error message */
  1712.         vim_memmove(newp, oldp, (size_t)col);
  1713.         ptr = newp + col;
  1714.         for (i = 0; i < count; ++i)
  1715.         {
  1716.             vim_memmove(ptr, y_array[0], (size_t)yanklen);
  1717.             ptr += yanklen;
  1718.         }
  1719.         vim_memmove(ptr, oldp + col, STRLEN(oldp + col) + 1);
  1720.         ml_replace(lnum, newp, FALSE);
  1721.         /* Put cursor on last putted char. */
  1722.         curwin->w_cursor.col += (colnr_t)(totlen - 1);
  1723.         }
  1724.         curbuf->b_op_end = curwin->w_cursor;
  1725.         /* For "CTRL-O p" in Insert mode, put cursor after last char */
  1726.         if (totlen && restart_edit)
  1727.         ++curwin->w_cursor.col;
  1728.         update_screenline();
  1729.     }
  1730.     else
  1731.     {
  1732.         while (--count >= 0)
  1733.         {
  1734.         i = 0;
  1735.         if (y_type == MCHAR)
  1736.         {
  1737.             /*
  1738.              * Split the current line in two at the insert position.
  1739.              * First insert y_array[size - 1] in front of second line.
  1740.              * Then append y_array[0] to first line.
  1741.              */
  1742.             ptr = ml_get(lnum) + col;
  1743.             totlen = STRLEN(y_array[y_size - 1]);
  1744.             newp = alloc_check((unsigned)(STRLEN(ptr) + totlen + 1));
  1745.             if (newp == NULL)
  1746.             goto error;
  1747.             STRCPY(newp, y_array[y_size - 1]);
  1748.             STRCAT(newp, ptr);
  1749.             /* insert second line */
  1750.             ml_append(lnum, newp, (colnr_t)0, FALSE);
  1751.             vim_free(newp);
  1752.  
  1753.             oldp = ml_get(lnum);
  1754.             newp = alloc_check((unsigned)(col + yanklen + 1));
  1755.             if (newp == NULL)
  1756.             goto error;
  1757.                         /* copy first part of line */
  1758.             vim_memmove(newp, oldp, (size_t)col);
  1759.                         /* append to first line */
  1760.             vim_memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
  1761.             ml_replace(lnum, newp, FALSE);
  1762.  
  1763.             curwin->w_cursor.lnum = lnum;
  1764.             i = 1;
  1765.         }
  1766.  
  1767.         while (i < y_size)
  1768.         {
  1769.             if ((y_type != MCHAR || i < y_size - 1) &&
  1770.             ml_append(lnum, y_array[i], (colnr_t)0, FALSE) == FAIL)
  1771.                 goto error;
  1772.             lnum++;
  1773.             i++;
  1774.             if (fix_indent)
  1775.             {
  1776.             old_pos = curwin->w_cursor;
  1777.             curwin->w_cursor.lnum = lnum;
  1778.             ptr = ml_get(lnum);
  1779. #if defined(SMARTINDENT) || defined(CINDENT)
  1780.             if (*ptr == '#'
  1781. # ifdef SMARTINDENT
  1782.                && curbuf->b_p_si
  1783. # endif
  1784. # ifdef CINDENT
  1785.                && curbuf->b_p_cin && in_cinkeys('#', ' ', TRUE)
  1786. # endif
  1787.                         )
  1788.                 indent = 0;     /* Leave # lines at start */
  1789.             else
  1790. #endif
  1791.                  if (*ptr == NUL)
  1792.                 indent = 0;     /* Ignore empty lines */
  1793.             else if (first_indent)
  1794.             {
  1795.                 indent_diff = orig_indent - get_indent();
  1796.                 indent = orig_indent;
  1797.                 first_indent = FALSE;
  1798.             }
  1799.             else if ((indent = get_indent() + indent_diff) < 0)
  1800.                 indent = 0;
  1801.             set_indent(indent, TRUE);
  1802.             curwin->w_cursor = old_pos;
  1803.             }
  1804.             ++nr_lines;
  1805.         }
  1806.         }
  1807.  
  1808.         /* put '] mark at last inserted character */
  1809.         curbuf->b_op_end.lnum = lnum;
  1810.         col = STRLEN(y_array[y_size - 1]);
  1811.         if (col > 1)
  1812.         curbuf->b_op_end.col = col - 1;
  1813.         else
  1814.         curbuf->b_op_end.col = 0;
  1815.  
  1816.         if (y_type == MLINE)
  1817.         {
  1818.         /* put cursor onfirst non-blank in first inserted line */
  1819.         curwin->w_cursor.col = 0;
  1820.         if (dir == FORWARD)
  1821.             ++curwin->w_cursor.lnum;
  1822.         beginline(BL_WHITE | BL_FIX);
  1823.         }
  1824.         else    /* put cursor on first inserted character */
  1825.         {
  1826.         curwin->w_cursor = new_cursor;
  1827.         }
  1828.  
  1829. error:
  1830.         if (y_type == MLINE)    /* adjust '[ mark */
  1831.         {
  1832.         curbuf->b_op_start.col = 0;
  1833.         if (dir == FORWARD)
  1834.             curbuf->b_op_start.lnum++;
  1835.         }
  1836.         mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR),
  1837.                          (linenr_t)MAXLNUM, nr_lines, 0L);
  1838.         update_topline();
  1839.         update_screen(NOT_VALID);
  1840.     }
  1841.     }
  1842.  
  1843.     msgmore(nr_lines);
  1844.     curwin->w_set_curswant = TRUE;
  1845.  
  1846. end:
  1847.     if (allocated)
  1848.     vim_free(insert_string);
  1849. }
  1850.  
  1851. /* Return the character name of the register with the given number */
  1852.     int
  1853. get_register_name(num)
  1854.     int num;
  1855. {
  1856.     if (num == -1)
  1857.     return '"';
  1858.     else if (num < 10)
  1859.     return num + '0';
  1860.     else if (num == DELETION_REGISTER)
  1861.     return '-';
  1862. #ifdef USE_CLIPBOARD
  1863.     else if (num == CLIPBOARD_REGISTER)
  1864.     return '*';
  1865. #endif
  1866.     else
  1867.     return num + 'a' - 10;
  1868. }
  1869.  
  1870. /*
  1871.  * display the contents of the yank registers
  1872.  */
  1873.     void
  1874. do_dis(arg)
  1875.     char_u *arg;
  1876. {
  1877.     int            i, n;
  1878.     long        j;
  1879.     char_u        *p;
  1880.     struct yankreg  *yb;
  1881.     char_u        name;
  1882.     int            attr;
  1883.  
  1884.     if (arg != NULL && *arg == NUL)
  1885.     arg = NULL;
  1886.     attr = highlight_attr[HLF_8];
  1887.  
  1888.     /* Highlight title */
  1889.     MSG_PUTS_TITLE("\n--- Registers ---");
  1890.     for (i = -1; i < NUM_REGISTERS; ++i)
  1891.     {
  1892.     if (i == -1)
  1893.     {
  1894.         if (y_previous != NULL)
  1895.         yb = y_previous;
  1896.         else
  1897.         yb = &(y_regs[0]);
  1898.     }
  1899.     else
  1900.         yb = &(y_regs[i]);
  1901.     name = get_register_name(i);
  1902.     if (yb->y_array != NULL && (arg == NULL ||
  1903.                            vim_strchr(arg, name) != NULL))
  1904.     {
  1905.         msg_putchar('\n');
  1906.         msg_putchar('"');
  1907.         msg_putchar(name);
  1908.         MSG_PUTS("   ");
  1909.  
  1910.         n = (int)Columns - 6;
  1911.         for (j = 0; j < yb->y_size && n > 1; ++j)
  1912.         {
  1913.         if (j)
  1914.         {
  1915.             MSG_PUTS_ATTR("^J", attr);
  1916.             n -= 2;
  1917.         }
  1918.         for (p = yb->y_array[j]; *p && (n -= charsize(*p)) >= 0; ++p)
  1919.             msg_outtrans_len(p, 1);
  1920.         }
  1921.         if (n > 1 && yb->y_type == MLINE)
  1922.         MSG_PUTS_ATTR("^J", attr);
  1923.         out_flush();            /* show one line at a time */
  1924.     }
  1925.     }
  1926.  
  1927.     /*
  1928.      * display last inserted text
  1929.      */
  1930.     if ((p = get_last_insert()) != NULL &&
  1931.     (arg == NULL || vim_strchr(arg, '.') != NULL))
  1932.     {
  1933.     MSG_PUTS("\n\".   ");
  1934.     dis_msg(p, TRUE);
  1935.     }
  1936.  
  1937.     /*
  1938.      * display last command line
  1939.      */
  1940.     if (last_cmdline != NULL && (arg == NULL || vim_strchr(arg, ':') != NULL))
  1941.     {
  1942.     MSG_PUTS("\n\":   ");
  1943.     dis_msg(last_cmdline, FALSE);
  1944.     }
  1945.  
  1946.     /*
  1947.      * display current file name
  1948.      */
  1949.     if (curbuf->b_fname != NULL &&
  1950.                 (arg == NULL || vim_strchr(arg, '%') != NULL))
  1951.     {
  1952.     MSG_PUTS("\n\"%   ");
  1953.     dis_msg(curbuf->b_fname, FALSE);
  1954.     }
  1955.  
  1956.     /*
  1957.      * display alternate file name
  1958.      */
  1959.     if (arg == NULL || vim_strchr(arg, '%') != NULL)
  1960.     {
  1961.     char_u        *fname;
  1962.     linenr_t    dummy;
  1963.  
  1964.     if (buflist_name_nr(0, &fname, &dummy) != FAIL)
  1965.     {
  1966.         MSG_PUTS("\n\"#   ");
  1967.         dis_msg(fname, FALSE);
  1968.     }
  1969.     }
  1970.  
  1971. #ifdef WANT_EVAL
  1972.     /*
  1973.      * display last used expression
  1974.      */
  1975.     if (expr_line != NULL && (arg == NULL || vim_strchr(arg, '=') != NULL))
  1976.     {
  1977.     MSG_PUTS("\n\"=   ");
  1978.     dis_msg(expr_line, FALSE);
  1979.     }
  1980. #endif
  1981. }
  1982.  
  1983. /*
  1984.  * display a string for do_dis()
  1985.  * truncate at end of screen line
  1986.  */
  1987.     void
  1988. dis_msg(p, skip_esc)
  1989.     char_u    *p;
  1990.     int        skip_esc;        /* if TRUE, ignore trailing ESC */
  1991. {
  1992.     int        n;
  1993.  
  1994.     n = (int)Columns - 6;
  1995.     while (*p && !(*p == ESC && skip_esc && *(p + 1) == NUL) &&
  1996.             (n -= charsize(*p)) >= 0)
  1997.     msg_outtrans_len(p++, 1);
  1998. }
  1999.  
  2000. /*
  2001.  * join 'count' lines (minimal 2), including u_save()
  2002.  */
  2003.     void
  2004. do_do_join(count, insert_space, redraw)
  2005.     long    count;
  2006.     int        insert_space;
  2007.     int        redraw;            /* can redraw, curwin->w_wcol valid */
  2008. {
  2009.     if (u_save((linenr_t)(curwin->w_cursor.lnum - 1),
  2010.             (linenr_t)(curwin->w_cursor.lnum + count)) == FAIL)
  2011.     return;
  2012.  
  2013.     if (count > 10)
  2014.     redraw = FALSE;            /* don't redraw each small change */
  2015.     while (--count > 0)
  2016.     {
  2017.     line_breakcheck();
  2018.     if (got_int || do_join(insert_space, redraw) == FAIL)
  2019.     {
  2020.         beep_flush();
  2021.         break;
  2022.     }
  2023.     }
  2024.     redraw_later(VALID_TO_CURSCHAR);
  2025.  
  2026.     /*
  2027.      * Need to update the screen if the line where the cursor is became too
  2028.      * long to fit on the screen.
  2029.      */
  2030.     update_topline_redraw();
  2031. }
  2032.  
  2033. /*
  2034.  * Join two lines at the cursor position.
  2035.  * "redraw" is TRUE when the screen should be updated.
  2036.  *
  2037.  * return FAIL for failure, OK ohterwise
  2038.  */
  2039.     int
  2040. do_join(insert_space, redraw)
  2041.     int        insert_space;
  2042.     int        redraw;
  2043. {
  2044.     char_u    *curr;
  2045.     char_u    *next;
  2046.     char_u    *newp;
  2047.     int        endcurr1, endcurr2;
  2048.     int        currsize;    /* size of the current line */
  2049.     int        nextsize;    /* size of the next line */
  2050.     int        spaces;        /* number of spaces to insert */
  2051.     int        rows_to_del = 0;/* number of rows on screen to delete */
  2052.     linenr_t    t;
  2053.  
  2054.     if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
  2055.     return FAIL;        /* can't join on last line */
  2056.  
  2057.     if (redraw)
  2058.     {
  2059.     /*
  2060.      * Check if we can really redraw:  w_cline_row and w_cline_height need
  2061.      * to be valid.  Try to make them valid by calling may_validate_crow()
  2062.      */
  2063.     if (may_validate_crow() == OK)
  2064.         rows_to_del = plines_m(curwin->w_cursor.lnum,
  2065.                            curwin->w_cursor.lnum + 1);
  2066.     else
  2067.         redraw = FALSE;
  2068.     }
  2069.  
  2070.     curr = ml_get_curline();
  2071.     currsize = STRLEN(curr);
  2072.     endcurr1 = endcurr2 = NUL;
  2073.     if (currsize > 0)
  2074.     {
  2075.     endcurr1 = *(curr + currsize - 1);
  2076.     if (currsize > 1)
  2077.         endcurr2 = *(curr + currsize - 2);
  2078.     }
  2079.  
  2080.     next = ml_get((linenr_t)(curwin->w_cursor.lnum + 1));
  2081.     spaces = 0;
  2082.     if (insert_space)
  2083.     {
  2084.     next = skipwhite(next);
  2085.     if (*next != ')' && currsize != 0 && endcurr1 != TAB)
  2086.     {
  2087.         /* don't add a space if the line is inding in a space */
  2088.         if (endcurr1 == ' ')
  2089.         endcurr1 = endcurr2;
  2090.         else
  2091.         ++spaces;
  2092.         /* extra space when 'joinspaces' set and line ends in '.' */
  2093.         if (       p_js
  2094.             && (endcurr1 == '.'
  2095.             || (vim_strchr(p_cpo, CPO_JOINSP) == NULL
  2096.                 && (endcurr1 == '?' || endcurr1 == '!'))))
  2097.         ++spaces;
  2098.     }
  2099.     }
  2100.     nextsize = STRLEN(next);
  2101.  
  2102.     newp = alloc_check((unsigned)(currsize + nextsize + spaces + 1));
  2103.     if (newp == NULL)
  2104.     return FAIL;
  2105.  
  2106.     /*
  2107.      * Insert the next line first, because we already have that pointer.
  2108.      * Curr has to be obtained again, because getting next will have
  2109.      * invalidated it.
  2110.      */
  2111.     vim_memmove(newp + currsize + spaces, next, (size_t)(nextsize + 1));
  2112.  
  2113.     curr = ml_get_curline();
  2114.     vim_memmove(newp, curr, (size_t)currsize);
  2115.  
  2116.     copy_spaces(newp + currsize, (size_t)spaces);
  2117.  
  2118.     ml_replace(curwin->w_cursor.lnum, newp, FALSE);
  2119.  
  2120.     /*
  2121.      * Delete the following line. To do this we move the cursor there
  2122.      * briefly, and then move it back. After del_lines() the cursor may
  2123.      * have moved up (last line deleted), so the current lnum is kept in t.
  2124.      */
  2125.     t = curwin->w_cursor.lnum;
  2126.     ++curwin->w_cursor.lnum;
  2127.     del_lines(1L, FALSE, FALSE);
  2128.     curwin->w_cursor.lnum = t;
  2129.  
  2130.     /*
  2131.      * the number of rows on the screen is reduced by the difference
  2132.      * in number of rows of the two old lines and the one new line
  2133.      */
  2134.     if (redraw)
  2135.     {
  2136.     rows_to_del -= plines(curwin->w_cursor.lnum);
  2137.     if (rows_to_del > 0)
  2138.         win_del_lines(curwin, curwin->w_cline_row + curwin->w_cline_height,
  2139.                              rows_to_del, TRUE, TRUE);
  2140.     }
  2141.  
  2142.     /*
  2143.      * go to first character of the joined line
  2144.      */
  2145.     if (currsize == 0)
  2146.     curwin->w_cursor.col = 0;
  2147.     else
  2148.     {
  2149.     curwin->w_cursor.col = currsize - 1;
  2150.     (void)oneright();
  2151.     }
  2152.     CHANGED;
  2153.  
  2154.     return OK;
  2155. }
  2156.  
  2157. /*
  2158.  * Return TRUE if the two comment leaders given are the same.  The cursor is
  2159.  * in the first line.  White-space is ignored.    Note that the whole of
  2160.  * 'leader1' must match 'leader2_len' characters from 'leader2' -- webb
  2161.  */
  2162.     static int
  2163. same_leader(leader1_len, leader1_flags, leader2_len, leader2_flags)
  2164.     int        leader1_len;
  2165.     char_u  *leader1_flags;
  2166.     int        leader2_len;
  2167.     char_u  *leader2_flags;
  2168. {
  2169.     int        idx1 = 0, idx2 = 0;
  2170.     char_u  *p;
  2171.     char_u  *line1;
  2172.     char_u  *line2;
  2173.  
  2174.     if (leader1_len == 0)
  2175.     return (leader2_len == 0);
  2176.  
  2177.     /*
  2178.      * If first leader has 'f' flag, the lines can be joined only if the
  2179.      * second line does not have a leader.
  2180.      * If first leader has 'e' flag, the lines can never be joined.
  2181.      * If fist leader has 's' flag, the lines can only be joined if there is
  2182.      * some text after it and the second line has the 'm' flag.
  2183.      */
  2184.     if (leader1_flags != NULL)
  2185.     {
  2186.     for (p = leader1_flags; *p && *p != ':'; ++p)
  2187.     {
  2188.         if (*p == COM_FIRST)
  2189.         return (leader2_len == 0);
  2190.         if (*p == COM_END)
  2191.         return FALSE;
  2192.         if (*p == COM_START)
  2193.         {
  2194.         if (*(ml_get_curline() + leader1_len) == NUL)
  2195.             return FALSE;
  2196.         if (leader2_flags == NULL || leader2_len == 0)
  2197.             return FALSE;
  2198.         for (p = leader2_flags; *p && *p != ':'; ++p)
  2199.             if (*p == COM_MIDDLE)
  2200.             return TRUE;
  2201.         return FALSE;
  2202.         }
  2203.     }
  2204.     }
  2205.  
  2206.     /*
  2207.      * Get current line and next line, compare the leaders.
  2208.      * The first line has to be saved, only one line can be locked at a time.
  2209.      */
  2210.     line1 = vim_strsave(ml_get_curline());
  2211.     if (line1 != NULL)
  2212.     {
  2213.     for (idx1 = 0; vim_iswhite(line1[idx1]); ++idx1)
  2214.         ;
  2215.     line2 = ml_get(curwin->w_cursor.lnum + 1);
  2216.     for (idx2 = 0; idx2 < leader2_len; ++idx2)
  2217.     {
  2218.         if (!vim_iswhite(line2[idx2]))
  2219.         {
  2220.         if (line1[idx1++] != line2[idx2])
  2221.             break;
  2222.         }
  2223.         else
  2224.         while (vim_iswhite(line1[idx1]))
  2225.             ++idx1;
  2226.     }
  2227.     vim_free(line1);
  2228.     }
  2229.     return (idx2 == leader2_len && idx1 == leader1_len);
  2230. }
  2231.  
  2232. /*
  2233.  * implementation of the format operator 'gq'
  2234.  */
  2235.     void
  2236. op_format(oap)
  2237.     OPARG    *oap;
  2238. {
  2239.     long    old_line_count = curbuf->b_ml.ml_line_count;
  2240.     int        is_not_par;        /* current line not part of parag. */
  2241.     int        next_is_not_par;    /* next line not part of paragraph */
  2242.     int        is_end_par;        /* at end of paragraph */
  2243.     int        prev_is_end_par = FALSE;/* prev. line not part of parag. */
  2244.     int        leader_len = 0;        /* leader len of current line */
  2245.     int        next_leader_len;    /* leader len of next line */
  2246.     char_u    *leader_flags = NULL;    /* flags for leader of current line */
  2247.     char_u    *next_leader_flags;    /* flags for leader of next line */
  2248.     int        advance = TRUE;
  2249.     int        second_indent = -1;
  2250.     int        do_second_indent;
  2251.     int        first_par_line = TRUE;
  2252.     int        smd_save;
  2253.     long    count;
  2254.     int        need_set_indent = TRUE;    /* set indent of next paragraph */
  2255.     int        force_format = FALSE;
  2256.     int        max_len;
  2257.     int        screenlines = -1;
  2258.  
  2259.     if (u_save((linenr_t)(oap->start.lnum - 1),
  2260.                        (linenr_t)(oap->end.lnum + 1)) == FAIL)
  2261.     return;
  2262.  
  2263.     /* When formatting less than a screenfull, will try to speed up redrawing
  2264.      * by inserting/deleting screen lines */
  2265.     if (oap->end.lnum - oap->start.lnum < Rows)
  2266.     screenlines = plines_m(oap->start.lnum, oap->end.lnum);
  2267.  
  2268.     /* length of a line to force formatting: 3 * 'tw' */
  2269.     max_len = comp_textwidth(TRUE) * 3;
  2270.  
  2271.     /* Set '[ mark at the start of the formatted area */
  2272.     curbuf->b_op_start = oap->start;
  2273.  
  2274.     /* check for 'q' and '2' in 'formatoptions' */
  2275.     fo_do_comments = has_format_option(FO_Q_COMS);
  2276.     do_second_indent = has_format_option(FO_Q_SECOND);
  2277.  
  2278.     /*
  2279.      * Get info about the previous and current line.
  2280.      */
  2281.     if (curwin->w_cursor.lnum > 1)
  2282.     is_not_par = fmt_check_par(curwin->w_cursor.lnum - 1,
  2283.                           &leader_len, &leader_flags);
  2284.     else
  2285.     is_not_par = TRUE;
  2286.     next_is_not_par = fmt_check_par(curwin->w_cursor.lnum,
  2287.                     &next_leader_len, &next_leader_flags);
  2288.     is_end_par = (is_not_par || next_is_not_par);
  2289.  
  2290.     curwin->w_cursor.lnum--;
  2291.     for (count = oap->line_count; count > 0 && !got_int; --count)
  2292.     {
  2293.     /*
  2294.      * Advance to next paragraph.
  2295.      */
  2296.     if (advance)
  2297.     {
  2298.         curwin->w_cursor.lnum++;
  2299.         prev_is_end_par = is_end_par;
  2300.         is_not_par = next_is_not_par;
  2301.         leader_len = next_leader_len;
  2302.         leader_flags = next_leader_flags;
  2303.     }
  2304.  
  2305.     /*
  2306.      * The last line to be formatted.
  2307.      */
  2308.     if (count == 1)
  2309.     {
  2310.         next_is_not_par = TRUE;
  2311.         next_leader_len = 0;
  2312.         next_leader_flags = NULL;
  2313.     }
  2314.     else
  2315.         next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1,
  2316.                     &next_leader_len, &next_leader_flags);
  2317.     advance = TRUE;
  2318.     is_end_par = (is_not_par || next_is_not_par);
  2319.  
  2320.     /*
  2321.      * Skip lines that are not in a paragraph.
  2322.      */
  2323.     if (!is_not_par)
  2324.     {
  2325.         /*
  2326.          * For the first line of a paragraph, check indent of second line.
  2327.          * Don't do this for comments and empty lines.
  2328.          */
  2329.         if (first_par_line
  2330.             && do_second_indent
  2331.             && prev_is_end_par
  2332.             && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count
  2333.             && leader_len == 0
  2334.             && next_leader_len == 0
  2335.             && !lineempty(curwin->w_cursor.lnum + 1))
  2336.         second_indent = get_indent_lnum(curwin->w_cursor.lnum + 1);
  2337.  
  2338.         /*
  2339.          * When the comment leader changes, it's the end of the paragraph.
  2340.          */
  2341.         if (curwin->w_cursor.lnum >= curbuf->b_ml.ml_line_count
  2342.             || !same_leader(leader_len, leader_flags,
  2343.                       next_leader_len, next_leader_flags))
  2344.         is_end_par = TRUE;
  2345.  
  2346.         /*
  2347.          * If we have got to the end of a paragraph, or the line is
  2348.          * getting long, format it.
  2349.          */
  2350.         if (is_end_par || force_format)
  2351.         {
  2352.         if (need_set_indent)
  2353.             /* replace indent in first line with minimal number of
  2354.              * tabs and spaces, according to current options */
  2355.             set_indent(get_indent(), TRUE);
  2356.  
  2357.         /* put cursor on last non-space */
  2358.         coladvance(MAXCOL);
  2359.         while (curwin->w_cursor.col && vim_isspace(gchar_cursor()))
  2360.             dec_cursor();
  2361.  
  2362.         /* do the formatting, without 'showmode' */
  2363.         State = INSERT;    /* for open_line() */
  2364.         smd_save = p_smd;
  2365.         p_smd = FALSE;
  2366.         insertchar(NUL, TRUE, second_indent, FALSE);
  2367.         State = NORMAL;
  2368.         p_smd = smd_save;
  2369.         second_indent = -1;
  2370.         /* at end of par.: need to set indent of next par. */
  2371.         need_set_indent = is_end_par;
  2372.         if (is_end_par)
  2373.             first_par_line = TRUE;
  2374.         force_format = FALSE;
  2375.         }
  2376.  
  2377.         /*
  2378.          * When still in same paragraph, join the lines together.  But
  2379.          * first delete the comment leader from the second line.
  2380.          */
  2381.         if (!is_end_par)
  2382.         {
  2383.         advance = FALSE;
  2384.         curwin->w_cursor.lnum++;
  2385.         curwin->w_cursor.col = 0;
  2386.         (void)del_chars((long)next_leader_len, FALSE);
  2387.         curwin->w_cursor.lnum--;
  2388.         if (do_join(TRUE, FALSE) == FAIL)
  2389.         {
  2390.             beep_flush();
  2391.             break;
  2392.         }
  2393.         first_par_line = FALSE;
  2394.         /* If the line is getting long, format it next time */
  2395.         if (STRLEN(ml_get_curline()) > (size_t)max_len)
  2396.             force_format = TRUE;
  2397.         else
  2398.             force_format = FALSE;
  2399.         }
  2400.     }
  2401.     line_breakcheck();
  2402.     }
  2403.     fo_do_comments = FALSE;
  2404.  
  2405.     /*
  2406.      * Try to correct the number of lines on the screen, to speed up
  2407.      * displaying.
  2408.      */
  2409.     if (screenlines > 0)
  2410.     {
  2411.     screenlines -= plines_m(oap->start.lnum, curwin->w_cursor.lnum);
  2412.     if (screenlines > 0)
  2413.         win_del_lines(curwin, curwin->w_cline_row, screenlines,
  2414.                                  FALSE, TRUE);
  2415.     else if (screenlines < 0)
  2416.         win_ins_lines(curwin, curwin->w_cline_row, screenlines,
  2417.                                  FALSE, TRUE);
  2418.     }
  2419.  
  2420.     /*
  2421.      * Leave the cursor at the first non-blank of the last formatted line.
  2422.      * If the cursor was moved one line back (e.g. with "Q}") go to the next
  2423.      * line, so "." will do the next lines.
  2424.      */
  2425.     if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
  2426.     ++curwin->w_cursor.lnum;
  2427.     beginline(BL_WHITE | BL_FIX);
  2428.     update_screen(NOT_VALID);
  2429.     msgmore(curbuf->b_ml.ml_line_count - old_line_count);
  2430.  
  2431.     /* put '] mark on the end of the formatted area */
  2432.     curbuf->b_op_end = curwin->w_cursor;
  2433. }
  2434.  
  2435. /*
  2436.  * Blank lines, and lines containing only the comment leader, are left
  2437.  * untouched by the formatting.  The function returns TRUE in this
  2438.  * case.  It also returns TRUE when a line starts with the end of a comment
  2439.  * ('e' in comment flags), so that this line is skipped, and not joined to the
  2440.  * previous line.  A new paragraph starts after a blank line, or when the
  2441.  * comment leader changes -- webb.
  2442.  */
  2443.     static int
  2444. fmt_check_par(lnum, leader_len, leader_flags)
  2445.     linenr_t    lnum;
  2446.     int        *leader_len;
  2447.     char_u    **leader_flags;
  2448. {
  2449.     char_u    *flags = NULL;        /* init for GCC */
  2450.     char_u    *ptr;
  2451.  
  2452.     ptr = ml_get(lnum);
  2453.     *leader_len = get_leader_len(ptr, leader_flags);
  2454.  
  2455.     if (*leader_len > 0)
  2456.     {
  2457.     /*
  2458.      * Search for 'e' flag in comment leader flags.
  2459.      */
  2460.     flags = *leader_flags;
  2461.     while (*flags && *flags != ':' && *flags != COM_END)
  2462.         ++flags;
  2463.     }
  2464.  
  2465.     return (ptr[*leader_len] == NUL ||
  2466.         (*leader_len > 0 && *flags == COM_END) ||
  2467.          startPS(lnum, NUL, FALSE));
  2468. }
  2469.  
  2470. /*
  2471.  * prepare a few things for block mode yank/delete/tilde
  2472.  *
  2473.  * for delete:
  2474.  * - textlen includes the first/last char to be (partly) deleted
  2475.  * - start/endspaces is the number of columns that are taken by the
  2476.  *   first/last deleted char minus the number of columns that have to be
  2477.  *   deleted.  for yank and tilde:
  2478.  * - textlen includes the first/last char to be wholly yanked
  2479.  * - start/endspaces is the number of columns of the first/last yanked char
  2480.  *   that are to be yanked.
  2481.  */
  2482.     static void
  2483. block_prep(oap, bd, lnum, is_del)
  2484.     OPARG        *oap;
  2485.     struct block_def    *bd;
  2486.     linenr_t        lnum;
  2487.     int            is_del;
  2488. {
  2489.     colnr_t    vcol;
  2490.     int        incr = 0;
  2491.     char_u    *pend;
  2492.     char_u    *pstart;
  2493.  
  2494.     bd->startspaces = 0;
  2495.     bd->endspaces = 0;
  2496.     bd->textlen = 0;
  2497.     bd->textcol = 0;
  2498.     vcol = 0;
  2499.     pstart = ml_get(lnum);
  2500.     while (vcol < oap->start_vcol && *pstart)
  2501.     {
  2502.     /* Count a tab for what it's worth (if list mode not on) */
  2503.     incr = lbr_chartabsize(pstart, (colnr_t)vcol);
  2504.     vcol += incr;
  2505.     ++pstart;
  2506.     ++bd->textcol;
  2507.     }
  2508.     if (vcol < oap->start_vcol)    /* line too short */
  2509.     {
  2510.     if (!is_del)
  2511.         bd->endspaces = oap->end_vcol - oap->start_vcol + 1;
  2512.     }
  2513.     else /* vcol >= oap->start_vcol */
  2514.     {
  2515.     bd->startspaces = vcol - oap->start_vcol;
  2516.     if (is_del && vcol > oap->start_vcol)
  2517.         bd->startspaces = incr - bd->startspaces;
  2518.     pend = pstart;
  2519.     if (vcol > oap->end_vcol)    /* it's all in one character */
  2520.     {
  2521.         bd->startspaces = oap->end_vcol - oap->start_vcol + 1;
  2522.         if (is_del)
  2523.         bd->startspaces = incr - bd->startspaces;
  2524.     }
  2525.     else
  2526.     {
  2527.         while (vcol <= oap->end_vcol && *pend)
  2528.         {
  2529.         /* Count a tab for what it's worth (if list mode not on) */
  2530.         incr = lbr_chartabsize(pend, (colnr_t)vcol);
  2531.         vcol += incr;
  2532.         ++pend;
  2533.         }
  2534.         if (vcol < oap->end_vcol && !is_del)    /* line too short */
  2535.         {
  2536.         bd->endspaces = oap->end_vcol - vcol;
  2537.         }
  2538.         else if (vcol > oap->end_vcol)
  2539.         {
  2540.         bd->endspaces = vcol - oap->end_vcol - 1;
  2541.         if (!is_del && pend != pstart && bd->endspaces)
  2542.             --pend;
  2543.         }
  2544.     }
  2545.     if (is_del && bd->startspaces)
  2546.     {
  2547.         --pstart;
  2548.         --bd->textcol;
  2549.     }
  2550.     bd->textlen = (int)(pend - pstart);
  2551.     }
  2552.     bd->textstart = pstart;
  2553. }
  2554.  
  2555. #ifdef RIGHTLEFT
  2556. static void reverse_line __ARGS((char_u *s));
  2557.  
  2558.     static void
  2559. reverse_line(s)
  2560.     char_u *s;
  2561. {
  2562.     int        i, j;
  2563.     char_u  c;
  2564.  
  2565.     if ((i = STRLEN(s) - 1) <= 0)
  2566.     return;
  2567.  
  2568.     curwin->w_cursor.col = i - curwin->w_cursor.col;
  2569.     for (j = 0; j < i; j++, i--)
  2570.     {
  2571.     c = s[i]; s[i] = s[j]; s[j] = c;
  2572.     }
  2573. }
  2574.  
  2575. # define RLADDSUBFIX() if (curwin->w_p_rl) reverse_line(ptr);
  2576. #else
  2577. # define RLADDSUBFIX()
  2578. #endif
  2579.  
  2580. /*
  2581.  * add or subtract 'Prenum1' from a number in a line
  2582.  * 'command' is CTRL-A for add, CTRL-X for subtract
  2583.  *
  2584.  * return FAIL for failure, OK otherwise
  2585.  */
  2586.     int
  2587. do_addsub(command, Prenum1)
  2588.     int        command;
  2589.     linenr_t    Prenum1;
  2590. {
  2591.     int            col;
  2592.     char_u        buf1[NUMBUFLEN];
  2593.     char_u        buf2[NUMBUFLEN];
  2594.     int            hex;        /* 'X' or 'x': hex; '0': octal */
  2595.     static int        hexupper = FALSE;    /* 0xABC */
  2596.     long        n;
  2597.     char_u        *ptr;
  2598.     int            c;
  2599.     int            length = 0;        /* character length of the number */
  2600.     int            todel;
  2601.     int            dohex;
  2602.     int            dooct;
  2603.     int            firstdigit;
  2604.  
  2605.     dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL);
  2606.     dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL);
  2607.  
  2608.     ptr = ml_get_curline();
  2609.     RLADDSUBFIX();
  2610.  
  2611.     /*
  2612.      * First check if we are on a hexadecimal number, after the "0x".
  2613.      */
  2614.     col = curwin->w_cursor.col;
  2615.     if (dohex)
  2616.     while (col > 0 && isxdigit(ptr[col]))
  2617.         --col;
  2618.     if (       dohex
  2619.         && col > 0
  2620.         && (ptr[col] == 'X'
  2621.         || ptr[col] == 'x')
  2622.         && ptr[col - 1] == '0'
  2623.         && isxdigit(ptr[col + 1]))
  2624.     {
  2625.     /*
  2626.      * Found hexadecimal number, move to its start.
  2627.      */
  2628.     --col;
  2629.     }
  2630.     else
  2631.     {
  2632.     /*
  2633.      * Search forward and then backward to find the start of number.
  2634.      */
  2635.     col = curwin->w_cursor.col;
  2636.  
  2637.     while (ptr[col] != NUL && !isdigit(ptr[col]))
  2638.         ++col;
  2639.  
  2640.     while (col > 0 && isdigit(ptr[col - 1]))
  2641.         --col;
  2642.     }
  2643.  
  2644.     /*
  2645.      * If a number was found, and saving for undo works, replace the number.
  2646.      */
  2647.     firstdigit = ptr[col];
  2648.     RLADDSUBFIX();
  2649.     if (!isdigit(firstdigit) || u_save_cursor() != OK)
  2650.     {
  2651.     beep_flush();
  2652.     return FAIL;
  2653.     }
  2654.  
  2655.     /* get ptr again, because u_save() may have changed it */
  2656.     ptr = ml_get_curline();
  2657.     RLADDSUBFIX();
  2658.  
  2659.     if (col > 0 && ptr[col - 1] == '-')        /* negative number */
  2660.     --col;
  2661.                         /* get the number value */
  2662.     n = vim_str2nr(ptr + col, &hex, &length, dooct, dohex);
  2663.  
  2664.     if (command == Ctrl('A'))            /* add or subtract */
  2665.     n += Prenum1;
  2666.     else
  2667.     n -= Prenum1;
  2668.  
  2669.     /*
  2670.      * Delete the old number.
  2671.      */
  2672.     curwin->w_cursor.col = col;
  2673.     todel = length;
  2674.     c = gchar_cursor();
  2675.     /*
  2676.      * Don't include the '-' in the length, only the length of the part
  2677.      * after it is kept the same.
  2678.      */
  2679.     if (c == '-')
  2680.     --length;
  2681.     while (todel-- > 0)
  2682.     {
  2683.     if (isalpha(c))
  2684.     {
  2685.         if (isupper(c))
  2686.         hexupper = TRUE;
  2687.         else
  2688.         hexupper = FALSE;
  2689.     }
  2690.     (void)del_char(FALSE);
  2691.     c = gchar_cursor();
  2692.     }
  2693.  
  2694.     /*
  2695.      * Prepare the leading characters in buf1[].
  2696.      */
  2697.     ptr = buf1;
  2698.     if (n < 0)
  2699.     {
  2700.     *ptr++ = '-';
  2701.     n = -n;
  2702.     }
  2703.     if (hex)
  2704.     {
  2705.     *ptr++ = '0';
  2706.     --length;
  2707.     }
  2708.     if (hex == 'x' || hex == 'X')
  2709.     {
  2710.     *ptr++ = hex;
  2711.     --length;
  2712.     }
  2713.  
  2714.     /*
  2715.      * Put the number characters in buf2[].
  2716.      */
  2717.     if (hex == 0)
  2718.     sprintf((char *)buf2, "%ld", n);
  2719.     else if (hex == '0')
  2720.     sprintf((char *)buf2, "%lo", n);
  2721.     else if (hex && hexupper)
  2722.     sprintf((char *)buf2, "%lX", n);
  2723.     else
  2724.     sprintf((char *)buf2, "%lx", n);
  2725.     length -= STRLEN(buf2);
  2726.  
  2727.     /*
  2728.      * adjust number of zeros to the new number of digits, so the
  2729.      * total length of the number remains the same
  2730.      */
  2731.     if (firstdigit == '0')
  2732.     while (length-- > 0)
  2733.         *ptr++ = '0';
  2734.     *ptr = NUL;
  2735.     STRCAT(buf1, buf2);
  2736.     ins_str(buf1);            /* insert the new number */
  2737.     --curwin->w_cursor.col;
  2738.     curwin->w_set_curswant = TRUE;
  2739. #ifdef RIGHTLEFT
  2740.     ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
  2741.     RLADDSUBFIX();
  2742. #endif
  2743.     update_screenline();
  2744.     return OK;
  2745. }
  2746.  
  2747. #ifdef VIMINFO
  2748.     int
  2749. read_viminfo_register(line, fp, force)
  2750.     char_u  *line;
  2751.     FILE    *fp;
  2752.     int        force;
  2753. {
  2754.     int        eof;
  2755.     int        do_it = TRUE;
  2756.     int        size;
  2757.     int        limit;
  2758.     int        i;
  2759.     int        set_prev = FALSE;
  2760.     char_u  *str;
  2761.     char_u  **array = NULL;
  2762.  
  2763.     /* We only get here (hopefully) if line[0] == '"' */
  2764.     str = line + 1;
  2765.     if (*str == '"')
  2766.     {
  2767.     set_prev = TRUE;
  2768.     str++;
  2769.     }
  2770.     if (!isalnum(*str) && *str != '-')
  2771.     {
  2772.     if (viminfo_error("Illegal register name", line))
  2773.         return TRUE;    /* too many errors, pretend end-of-file */
  2774.     do_it = FALSE;
  2775.     }
  2776.     get_yank_register(*str++, FALSE);
  2777.     if (!force && y_current->y_array != NULL)
  2778.     do_it = FALSE;
  2779.     size = 0;
  2780.     limit = 100;    /* Optimized for registers containing <= 100 lines */
  2781.     if (do_it)
  2782.     {
  2783.     if (set_prev)
  2784.         y_previous = y_current;
  2785.     vim_free(y_current->y_array);
  2786.     array = y_current->y_array =
  2787.                (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
  2788.     str = skipwhite(str);
  2789.     if (STRNCMP(str, "CHAR", 4) == 0)
  2790.         y_current->y_type = MCHAR;
  2791.     else if (STRNCMP(str, "BLOCK", 5) == 0)
  2792.         y_current->y_type = MBLOCK;
  2793.     else
  2794.         y_current->y_type = MLINE;
  2795.     }
  2796.     while (!(eof = vim_fgets(line, LSIZE, fp)) && line[0] == TAB)
  2797.     {
  2798.     if (do_it)
  2799.     {
  2800.         if (size >= limit)
  2801.         {
  2802.         y_current->y_array = (char_u **)
  2803.                   alloc((unsigned)(limit * 2 * sizeof(char_u *)));
  2804.         for (i = 0; i < limit; i++)
  2805.             y_current->y_array[i] = array[i];
  2806.         vim_free(array);
  2807.         limit *= 2;
  2808.         array = y_current->y_array;
  2809.         }
  2810.         viminfo_readstring(line);
  2811.         str = vim_strsave(line + 1);
  2812.         if (str != NULL)
  2813.         array[size++] = str;
  2814.         else
  2815.         do_it = FALSE;
  2816.     }
  2817.     }
  2818.     if (do_it)
  2819.     {
  2820.     if (size == 0)
  2821.     {
  2822.         vim_free(array);
  2823.         y_current->y_array = NULL;
  2824.     }
  2825.     else if (size < limit)
  2826.     {
  2827.         y_current->y_array =
  2828.             (char_u **)alloc((unsigned)(size * sizeof(char_u *)));
  2829.         for (i = 0; i < size; i++)
  2830.         y_current->y_array[i] = array[i];
  2831.         vim_free(array);
  2832.     }
  2833.     y_current->y_size = size;
  2834.     }
  2835.     return eof;
  2836. }
  2837.  
  2838.     void
  2839. write_viminfo_registers(fp)
  2840.     FILE    *fp;
  2841. {
  2842.     int        i, j;
  2843.     char_u  *type;
  2844.     char_u  c;
  2845.     int        num_lines;
  2846.     int        max_num_lines;
  2847.  
  2848.     fprintf(fp, "\n# Registers:\n");
  2849.  
  2850.     max_num_lines = get_viminfo_parameter('"');
  2851.     if (max_num_lines == 0)
  2852.     return;
  2853.     for (i = 0; i < NUM_REGISTERS; i++)
  2854.     {
  2855.     if (y_regs[i].y_array == NULL)
  2856.         continue;
  2857. #ifdef USE_CLIPBOARD
  2858.     /* Skip '*' register, we don't want it back next time */
  2859.     if (i == CLIPBOARD_REGISTER)
  2860.         continue;
  2861. #endif
  2862.     switch (y_regs[i].y_type)
  2863.     {
  2864.         case MLINE:
  2865.         type = (char_u *)"LINE";
  2866.         break;
  2867.         case MCHAR:
  2868.         type = (char_u *)"CHAR";
  2869.         break;
  2870.         case MBLOCK:
  2871.         type = (char_u *)"BLOCK";
  2872.         break;
  2873.         default:
  2874.         sprintf((char *)IObuff, "Unknown register type %d",
  2875.             y_regs[i].y_type);
  2876.         emsg(IObuff);
  2877.         type = (char_u *)"LINE";
  2878.         break;
  2879.     }
  2880.     if (y_previous == &y_regs[i])
  2881.         fprintf(fp, "\"");
  2882.     if (i == DELETION_REGISTER)
  2883.         c = '-';
  2884.     else if (i < 10)
  2885.         c = '0' + i;
  2886.     else
  2887.         c = 'a' + i - 10;
  2888.     fprintf(fp, "\"%c\t%s\n", c, type);
  2889.     num_lines = y_regs[i].y_size;
  2890.  
  2891.     /* If max_num_lines < 0, then we save ALL the lines in the register */
  2892.     if (max_num_lines > 0 && num_lines > max_num_lines)
  2893.         num_lines = max_num_lines;
  2894.     for (j = 0; j < num_lines; j++)
  2895.     {
  2896.         putc('\t', fp);
  2897.         viminfo_writestring(fp, y_regs[i].y_array[j]);
  2898.     }
  2899.     }
  2900. }
  2901. #endif /* VIMINFO */
  2902.  
  2903. #if defined(USE_CLIPBOARD) || defined(PROTO)
  2904. /*
  2905.  * Text selection stuff that uses the GUI selection register '*'.  When using a
  2906.  * GUI this may be text from another window, otherwise it is the last text we
  2907.  * had highlighted with VIsual mode.  With mouse support, clicking the middle
  2908.  * button performs the paste, otherwise you will need to do <"*p>.
  2909.  */
  2910.  
  2911.     void
  2912. clip_free_selection()
  2913. {
  2914.     struct yankreg *y_ptr = y_current;
  2915.  
  2916.     y_current = &y_regs[CLIPBOARD_REGISTER];        /* '*' register */
  2917.     free_yank_all();
  2918.     y_current->y_size = 0;
  2919.     y_current = y_ptr;
  2920. }
  2921.  
  2922. /*
  2923.  * Get the selected text and put it in the gui text register '*'.
  2924.  */
  2925.     void
  2926. clip_get_selection()
  2927. {
  2928.     struct yankreg *old_y_previous, *old_y_current;
  2929.     FPOS    old_cursor, old_visual;
  2930.     colnr_t old_curswant;
  2931.     int        old_set_curswant;
  2932.     OPARG   oa;
  2933.     CMDARG  ca;
  2934.  
  2935.     if (clipboard.owned)
  2936.     {
  2937.     if (y_regs[CLIPBOARD_REGISTER].y_array != NULL)
  2938.         return;
  2939.  
  2940.     /* Get the text between clipboard.start & clipboard.end */
  2941.     old_y_previous = y_previous;
  2942.     old_y_current = y_current;
  2943.     old_cursor = curwin->w_cursor;
  2944.     old_curswant = curwin->w_curswant;
  2945.     old_set_curswant = curwin->w_set_curswant;
  2946.     old_visual = VIsual;
  2947.     clear_oparg(&oa);
  2948.     oa.regname = '*';
  2949.     oa.op_type = OP_YANK;
  2950.     vim_memset(&ca, 0, sizeof(ca));
  2951.     ca.oap = &oa;
  2952.     ca.cmdchar = 'y';
  2953.     ca.count1 = 1;
  2954.     do_pending_operator(&ca, NULL, NULL, 0, TRUE, TRUE);
  2955.     y_previous = old_y_previous;
  2956.     y_current = old_y_current;
  2957.     curwin->w_cursor = old_cursor;
  2958.     curwin->w_curswant = old_curswant;
  2959.     curwin->w_set_curswant = old_set_curswant;
  2960.     VIsual = old_visual;
  2961.     }
  2962.     else
  2963.     {
  2964.     clip_free_selection();
  2965.  
  2966.     /* Try to get selected text from another window */
  2967.     clip_mch_request_selection();
  2968.     }
  2969. }
  2970.  
  2971. /* Convert from the GUI selection string into the '*' register */
  2972.     void
  2973. clip_yank_selection(type, str, len)
  2974.     int        type;
  2975.     char_u  *str;
  2976.     long    len;
  2977. {
  2978.     struct yankreg *y_ptr = &y_regs[CLIPBOARD_REGISTER];    /* '*' register */
  2979.  
  2980.     clip_free_selection();
  2981.  
  2982.     str_to_reg(y_ptr, type, str, len);
  2983. }
  2984.  
  2985. /*
  2986.  * Convert the '*' register into a GUI selection string returned in *str with
  2987.  * length *len.
  2988.  */
  2989.     int
  2990. clip_convert_selection(str, len)
  2991.     char_u  **str;
  2992.     long_u  *len;
  2993. {
  2994.     struct yankreg *y_ptr = &y_regs[CLIPBOARD_REGISTER];    /* '*' register */
  2995.     char_u  *p;
  2996.     int        lnum;
  2997.     int        i, j;
  2998.     int_u   eolsize;
  2999.  
  3000. #ifdef USE_CRNL
  3001.     eolsize = 2;
  3002. #else
  3003.     eolsize = 1;
  3004. #endif
  3005.  
  3006.     *str = NULL;
  3007.     *len = 0;
  3008.     if (y_ptr->y_array == NULL)
  3009.     return -1;
  3010.  
  3011.     for (i = 0; i < y_ptr->y_size; i++)
  3012.     *len += STRLEN(y_ptr->y_array[i]) + eolsize;
  3013.  
  3014.     /*
  3015.      * Don't want newline character at end of last line if we're in MCHAR mode.
  3016.      */
  3017.     if (y_ptr->y_type == MCHAR && *len > eolsize)
  3018.     *len -= eolsize;
  3019.  
  3020.     p = *str = lalloc(*len, TRUE);
  3021.     if (p == NULL)
  3022.     return -1;
  3023.     lnum = 0;
  3024.     for (i = 0, j = 0; i < (int)*len; i++, j++)
  3025.     {
  3026.     if (y_ptr->y_array[lnum][j] == '\n')
  3027.         p[i] = NUL;
  3028.     else if (y_ptr->y_array[lnum][j] == NUL)
  3029.     {
  3030. #ifdef USE_CRNL
  3031.         p[i++] = '\r';
  3032. #endif
  3033. #ifdef USE_CR
  3034.         p[i] = '\r';
  3035. #else
  3036.         p[i] = '\n';
  3037. #endif
  3038.         lnum++;
  3039.         j = -1;
  3040.     }
  3041.     else
  3042.         p[i] = y_ptr->y_array[lnum][j];
  3043.     }
  3044.     return y_ptr->y_type;
  3045. }
  3046. #endif /* USE_CLIPBOARD || PROTO */
  3047.  
  3048. #ifdef WANT_EVAL
  3049. /*
  3050.  * Return the contents of a register as a single allocated string.
  3051.  * Used for "@r" in expressions.
  3052.  * Returns NULL for error.
  3053.  */
  3054.     char_u *
  3055. get_reg_contents(regname)
  3056.     int        regname;
  3057. {
  3058.     long    i;
  3059.     char_u  *retval;
  3060.     int        allocated;
  3061.     long    len;
  3062.  
  3063.     /* Don't allow using an expression register inside an expression */
  3064.     if (regname == '=')
  3065.     return NULL;
  3066.  
  3067.     if (regname == '@')        /* "@@" is used for unnamed register */
  3068.     regname = '"';
  3069.  
  3070.     /* check for valid regname */
  3071.     if (regname != NUL && !valid_yank_reg(regname, FALSE))
  3072.     return NULL;
  3073.  
  3074. #ifdef USE_CLIPBOARD
  3075.     if (regname == '*')
  3076.     clip_get_selection();        /* may fill * register */
  3077. #endif
  3078.  
  3079.     if (get_spec_reg(regname, &retval, &allocated))
  3080.     {
  3081.     if (retval == NULL)
  3082.         return NULL;
  3083.     if (!allocated)
  3084.         retval = vim_strsave(retval);
  3085.     return retval;
  3086.     }
  3087.  
  3088.     get_yank_register(regname, FALSE);
  3089.     if (y_current->y_array == NULL)
  3090.     return NULL;
  3091.  
  3092.     /*
  3093.      * Compute length of resulting string.
  3094.      */
  3095.     len = 0;
  3096.     for (i = 0; i < y_current->y_size; ++i)
  3097.     {
  3098.     len += STRLEN(y_current->y_array[i]);
  3099.     /*
  3100.      * Insert a newline between lines and after last line if
  3101.      * y_type is MLINE.
  3102.      */
  3103.     if (y_current->y_type == MLINE || i < y_current->y_size - 1)
  3104.         ++len;
  3105.     }
  3106.  
  3107.     retval = lalloc(len + 1, TRUE);
  3108.  
  3109.     /*
  3110.      * Copy the lines of the yank register into the string.
  3111.      */
  3112.     if (retval != NULL)
  3113.     {
  3114.     len = 0;
  3115.     for (i = 0; i < y_current->y_size; ++i)
  3116.     {
  3117.         STRCPY(retval + len, y_current->y_array[i]);
  3118.         len += STRLEN(retval + len);
  3119.  
  3120.         /*
  3121.          * Insert a NL between lines and after the last line if y_type is
  3122.          * MLINE.
  3123.          */
  3124.         if (y_current->y_type == MLINE || i < y_current->y_size - 1)
  3125.         retval[len++] = '\n';
  3126.     }
  3127.     retval[len] = NUL;
  3128.     }
  3129.  
  3130.     return retval;
  3131. }
  3132.  
  3133. /*
  3134.  * Store string 'str' in register 'name'.
  3135.  * Careful: 'str' is modified, you may have to use a copy!
  3136.  * If 'str' ends in '\n' or '\r', use linewise, otherwise use characterwise.
  3137.  */
  3138.     void
  3139. write_reg_contents(name, str)
  3140.     int        name;
  3141.     char_u  *str;
  3142. {
  3143.     struct yankreg  *old_y_previous, *old_y_current;
  3144.     long        len;
  3145.  
  3146.     if (!valid_yank_reg(name, TRUE))        /* check for valid reg name */
  3147.     {
  3148.     EMSG2("Invalid register name: '%s'", transchar(name));
  3149.     return;
  3150.     }
  3151.  
  3152.     /* Don't want to change the current (unnamed) register */
  3153.     old_y_previous = y_previous;
  3154.     old_y_current = y_current;
  3155.  
  3156.     get_yank_register(name, TRUE);
  3157.     if (!y_append)
  3158.     free_yank_all();
  3159.     len = STRLEN(str);
  3160.     str_to_reg(y_current,
  3161.         (len > 0 && (str[len - 1] == '\n' || str[len -1] == '\r'))
  3162.          ? MLINE : MCHAR, str, len);
  3163.     y_previous = old_y_previous;
  3164.     y_current = old_y_current;
  3165. }
  3166. #endif    /* WANT_EVAL */
  3167.  
  3168. #if defined(USE_CLIPBOARD) || defined(WANT_EVAL)
  3169. /*
  3170.  * Put a string into a register.  When the register is not empty, the string
  3171.  * is appended.
  3172.  */
  3173.     static void
  3174. str_to_reg(y_ptr, type, str, len)
  3175.     struct yankreg    *y_ptr;        /* pointer to yank register */
  3176.     int            type;        /* MCHAR or MLINE */
  3177.     char_u        *str;        /* string to put in register */
  3178.     long        len;        /* lenght of string */
  3179. {
  3180.     int        lnum;
  3181.     long    start;
  3182.     long    i;
  3183.     int        extra;
  3184.     int        newlines;            /* number of lines added */
  3185.     int        extraline = 0;        /* extra line at the end */
  3186.     int        append = FALSE;        /* append to last line in register */
  3187.     char_u  *s;
  3188.     char_u  **pp;
  3189.  
  3190.     if (y_ptr->y_array == NULL)        /* NULL means emtpy register */
  3191.     y_ptr->y_size = 0;
  3192.  
  3193.     /*
  3194.      * Count the number of lines within the string
  3195.      */
  3196.     newlines = 0;
  3197.     for (i = 0; i < len; i++)
  3198.     if (str[i] == '\n')
  3199.         ++newlines;
  3200.     if (type == MCHAR || len == 0 || str[len - 1] != '\n')
  3201.     {
  3202.     extraline = 1;
  3203.     ++newlines;    /* count extra newline at the end */
  3204.     }
  3205.     if (y_ptr->y_size > 0 && y_ptr->y_type == MCHAR)
  3206.     {
  3207.     append = TRUE;
  3208.     --newlines;    /* uncount newline when appending first line */
  3209.     }
  3210.  
  3211.     /*
  3212.      * Allocate an array to hold the pointers to the new register lines.
  3213.      * If the register was not empty, move the existing lines to the new array.
  3214.      */
  3215.     pp = (char_u **)lalloc_clear((y_ptr->y_size + newlines)
  3216.                             * sizeof(char_u *), TRUE);
  3217.     if (pp == NULL)    /* out of memory */
  3218.     return;
  3219.     for (lnum = 0; lnum < y_ptr->y_size; ++lnum)
  3220.     pp[lnum] = y_ptr->y_array[lnum];
  3221.     vim_free(y_ptr->y_array);
  3222.     y_ptr->y_array = pp;
  3223.  
  3224.     /*
  3225.      * Find the end of each line and save it into the array.
  3226.      */
  3227.     for (start = 0; start < len + extraline; start += i + 1)
  3228.     {
  3229.     for (i = start; i < len; ++i)    /* find the end of the line */
  3230.         if (str[i] == '\n')
  3231.         break;
  3232.     i -= start;            /* i is now length of line */
  3233.     if (append)
  3234.     {
  3235.         --lnum;
  3236.         extra = STRLEN(y_ptr->y_array[lnum]);
  3237.     }
  3238.     else
  3239.         extra = 0;
  3240.     s = alloc((unsigned)(i + extra + 1));
  3241.     if (s == NULL)
  3242.         break;
  3243.     if (extra)
  3244.     {
  3245.         vim_memmove(s, y_ptr->y_array[lnum], (size_t)extra);
  3246.         vim_free(y_ptr->y_array[lnum]);
  3247.     }
  3248.     if (i)
  3249.         vim_memmove(s + extra, str + start, (size_t)i);
  3250.     extra += i;
  3251.     s[extra] = NUL;
  3252.     y_ptr->y_array[lnum++] = s;
  3253.     while (--extra >= 0)
  3254.     {
  3255.         if (*s == NUL)
  3256.         *s = '\n';        /* replace NUL with newline */
  3257.         ++s;
  3258.     }
  3259.     append = FALSE;            /* only first line is appended */
  3260.     }
  3261.     y_ptr->y_type = type;
  3262.     y_ptr->y_size = lnum;
  3263. }
  3264. #endif /* USE_CLIPBOARD || WANT_EVAL || PROTO */
  3265.  
  3266.     void
  3267. clear_oparg(oap)
  3268.     OPARG    *oap;
  3269. {
  3270.     vim_memset(oap, 0, sizeof(OPARG));
  3271. }
  3272.